ADSP基础入门 第6讲 Blackfin嵌入式C编程.ppt_第1页
ADSP基础入门 第6讲 Blackfin嵌入式C编程.ppt_第2页
ADSP基础入门 第6讲 Blackfin嵌入式C编程.ppt_第3页
ADSP基础入门 第6讲 Blackfin嵌入式C编程.ppt_第4页
ADSP基础入门 第6讲 Blackfin嵌入式C编程.ppt_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

BlackfinCprogrammingBlackfin嵌入式C编程 电子工程学院陈子为 2 C C 编译器简介VisualDSP 使用ccblkfn编译器 此C C 编译器有如下功能 处理C和C 源文件 产生机器级源代码和目标文件 在目标文件中包含可重定位的代码和调试信息 在处理器存储区中提供可由链接器替换的可重定位数据和程序存储段 C C 编译器处理C和C 语言源文件并生成Blackfin汇编源文件 汇编源文件由BlackfinDSP系列汇编器 easmblkfn exe 汇编产生 汇编器进一步产生ELF ExecutableandLinkableFormat 目标文件 由它可以链接 使用链接器 产生一个BlackfinDSP可执行文件或将其包含在一个档案文件库 elfar exe 中 编译器如何控制处理过程的汇编 链接和存档阶段取决于输入源文件和所用的编译器选项 3 BlackfinC C 编译器支持的数据类型 4 注意 Blackfin定点处理器只支持定点运算 宽度最高32位 所以浮点数据及64位数据不直接支持 需通过软件转换来实现转换 速度会降低很多 分数形式的数据类型fract16和fract32并不是实际存在的数据类型 事实上就是以short和int形式存储 即1 15的16位有符号short整型 定点型 1 31的32位有符号int整型 定点型 用于表示有符号小数 typedefshortfract16 typedefintfract32 使用该数据类型时需要先 include 5 逻辑操作符与位操作符逻辑操作符 与 设置LCD控制寄存器的最低位来打开LCD 位异或 将某个位或某些位取反 6 右移 实现除法 除以2n 如果除数是2的n次方 编译器就会调用移位操作来完成除法运算 无符号除法比有符合除法的效率高 求反 将每一位取反 例如 HC595 SendDat DISP TAB i 输出LED显示数据 7 Volatile的用法volatile在英文字典的解释为 易变的 反复无常的 性格 编译器有一种技术叫数据流分析 分析程序中的变量在哪里赋值 哪里使用 哪里失效 分析结果可以用于常量合并 常量传播等优化 当它觉察到你的代码没有修改变量的值时 它就可能在你访问变量时提供上次访问的缓冲值 这能够提高程序的效率 但这些优化可能会带来问题 特别是对硬件寄存器操作的程序中 这时需要用volatile关键词来禁止做这些优化 告诉编译器 变量已经变化 不要用缓存值 变量可能会随时改变 不要对其优化 而是每次用的时候去读写该变量 8 使用volatile变量的场合硬件寄存器通常要加volatile说明 definepFlashA PortA Dir volatileunsignedchar 0 x20270006在中断服务程序中修改的供其它程序检测的变量需要加volatile 例如 中断服务程序常常通过改变一些全局变量来通知应用程序某个外部事件已经发生 这些全局变量不应该被优化 多任务环境中各任务间共享的标志应该加volatile 9 C C 编译语言扩展编译器支持对ISO ANSI标准的C语言和C 语言的扩展 为了使C C 扩展中附加关键字与ISO ANSI标准C C 的关键字不冲突 C C 扩展中附加关键字在形式上均以双下划线 打头 标准C C 关键字用一个下划线 打头 编译器扩展C C 关键字用两个下划线 打头 标准库函数名用一个下划线 打头 编译器扩展的库函数 由编译器给出的内嵌函数 名用两个下划线 打头 10 C C 编译语言扩展内联函数关键字 inline ccblkfn的inline关键字使声明为inline类型的函数代码内嵌到调用它的地方 inline是C 的标准特点 ccblkfn将它作为C的扩展 使用该选项节省了调用函数的额外时间开销 因此提高了程序执行速度 内联汇编语言关键字 asm ccblkfn的asm 结构可在C C 函数中内嵌BlackfinDSP汇编语言指令 对程序中用C或C 不易或不能高效实现的地方可以用asm 结构利用汇编语言实现 11 指定要放置数据的存储器位置的关键字 section section关键字使编译器在汇编器的交叉输出文件的 SECTION中放置目标或函数代码 可以用section 中的字符串参数命名 SECTION 如果对目标或函数声明没有指定section 编译器会使用默认值 例如 section buffer intin 1024 include sine dat 指针受限关键字 restrict restrict关键字支持受限制的指针特性 restrict的使用局限于声明一个指针 并指明指针是访问它所指向内容的惟一途径 简单来说 restrict使指针不能使用别名 即两个不同受限指针不能指向同一个对象 指针不能有别名 12 内置函数 buildin 编译器支持使用内置函数 从而有效利用硬件资源 有关这些函数的信息已经内嵌在编译器中 用户程序使用正常的函数调用句法调用它们 编译器处理此类函数调用 会生成一条或多条机器指令 就像处理正常的操作符 如 和 那样 内置函数名是以 builtin 开始的 头文件为内置函数定义一个可读性更好的名称 这个名称不使用 builtin 前缀 例如在ccblkfn h中 definesysreg write A B builtin sysreg write A B 13 预处理命令预处理器在编译器之前运行 它在编译之前对等待处理的代码进行预处理 预处理器指令以 开始 以回车符结束 不能有 号 如何预处理器指令长于一行 用 续行 预处理器指令对大小写敏感 必须用小写 预处理命令的功能如下包含系统和用户定义头文件 例如 include定义宏和标志常量 例如 define提供条件汇编和编译 例如 ifdef ifndef if 均以 endif结束 14 if和 endif条件编译指令 例如 defineLCD TYPEMLCD 320 240 if LCD TYPE MLCD 320 240 defineSCR XSIZE 640 defineSCR XSIZE 480 defineLCD XSIZE 320 defineLCD XSIZE 240 if LCD TYPE CLCD 240 320 defineSCR XSIZE 640 defineSCR XSIZE 480 defineLCD XSIZE 240 defineLCD XSIZE 320 endif 技巧 在程序调试中 可以用 if临时注释掉一段代码 如下所示 if0 endif当需要这段代码时 只需将0变为1即可 15 系统库函数 内置函数 编译器内置函数 CompilerBuiltinFunction 主要针对一些常用的操作 其实现大多与处理器硬件电路有关 内置函数一般采用汇编语言编写 一旦用户调用此函数 编译器直接映射到相应的汇编代码中 会被编译器识别出来 使用固定的汇编语句来代替库函数的调用 运行效率很高 有一些内置函数是系统管理函数 这些内置函数将系统管理的各项操作封装成函数 直接调用这些内置函数将能提高代码的可读性 例如 获取系统时钟周期的函数示例如下 Clevelfunctionswithseveralassemblyinstructionsandexpandedintocompilerintermediateinstruction 16 系统库函数 内部函数通常支持16位或32位数的操作包括libc libdsp libetsi libio lwip libbtc等库 支持如下的操作和函数 小数值内部函数ETSI 欧洲电信标准协会 标准的支持复数小数数据和操作Viterbi编码和解码函数循环缓冲区函数高低字节交换 Endian swapping 函数系统内部函数视频操作函数未对齐的数据函数内部函数支持防止溢出的饱和算法 这一点与标准C程序不同 库文件位置 安装目录 Blackfin lib 头文件位置 安装目录 Blackfin includes 源代码位置 安装目录 Blackfin lib src 可根据需要对源代码进行修改 请将文件复制到其它地方 重命名后再进行修改 调用库文件时需要先引用相应的头文件 17 示例 完成一个256阶的FIR滤波器 18 ETSIBuiltins fullyoptimisedFractionalarithmetictoastandardspecification EuropeanTelecommunicationsStandardsInstitute sfractfunctionscarefullymappedontothecompilerbuilt ins 头文件libetsi h包含了ETSI内部函数 ETSI函数与小数值内部函数类似 可以完成16位和32位小数值算术运算 还包含复数小数运算 add sub abs s shl shr mult mult r negate round L add L sub L abs L negate L shl L shr L mult L mac L msu saturate extract h extract l L deposit l L deposit h div s norm s norm l L Extract L Comp Mpy 32 Mpy 32 16 使用时需包含 include 且需要将libetsi dlb库加入到工程中Highlyrecommended 19 C C Run time环境 运行时环境是为了使应用程序能够正常运行需要维护的一套环境 例如 系统复位跳转到开始地址后要执行的代码 这些代码 即C C Run timeheaders 又称CRT 需要将寄存器的值由未知状态设置为已知状态 完成用于维护工作环境的操作 运行时环境还包括C C 语言中的函数调用约定 在运行时环境中 有一部分是约定好了的 由编译器自己自动完成 另有一部分是需要编写代码实现的 如重启时的CRT代码 ADI提供了默认的CRT文件 即安装目录下Blackfin lib src libc crt中的basiccrt s文件 20 CRun TimeHeader basiccrt s SetsUpCRun Time CRT Environment SetsUpStackPointer EnablesCycleCountersforBenchmarkingCode ConfiguresCache IfRequested ChangeClock VoltageSettings IfRequestedCanBeModifiedThroughProjectOptionsWindow 21 C C Run timeLibrary C C Run timeLibrary是实现运行时环境时可能被代码使用的函数 宏定义 类模板的集合 这个库提供了对语言而讲最基本的应用 分配内存 字符 字符串的转换 数学计算等 头文件位置 安装目录 Blackfin includes 源代码位置 安装目录 Blackfin lib src libc 函数名是基于C C 语言的 如需要在汇编语言里调用它们 需要使用这些函数的汇编版本的名称 一般后缀带 s 例如write s asm 22 C C Run timeLibrary提供的库函数 ccblkfn h与Blackfin系列DSP系统功能相关的函数 ctype h针对字符处理的函数 包括isdigit islower toupper等等math h数学运算函数 乘方 三角函数 对数 指数等 signal h标准ANSI中的信号相关功能的函数 主要用于处理C程序中的外部中断信号或定时器中断信号 包括raise 建立和强制使能低优先级的中断 signal interruptstdio h输入 输出操作 会受到中断干扰 不能在中断服务程序中调用这些函数 包括 fwrite fclose printf等stdlib h提供C语言标准中通用的功能 像定点算术功能 abs div rand 通用字符串至数字的转换 存储器内存空间管理 malloc free 之类string h处理字符串的函数 例如strcpy strcmp memcpy等time h与时间相关的数据类型 宏 以及与表达式相关的用于时间计算的信息 如clock asctime ctime等 23 C C Run timeLibrary提供的库函数 float h浮点数据的处理limits h定义Cdatatype的最大 最小值等等iso646 h布尔运算device h交互设备驱动程序的宏和数据结构device int h交互设备驱动的列举和原型errno h错误处理 加入C C Run timeLibrary库的方法ProjectOption Link General Search找到lib532 dlb的路径或者用命令 lc532 C库libc532 dlb lcpp532 C 库libcpp532 dlb 使用时参考VisualDSP 4 5C C CompilerandLibraryManualforBlackfinProcessors pdf 24 DSPRun timeLibrary libdsp 支持很多通用的DSP算法 例如滤波 FFT 矢量和矩阵函数 数学函数 窗函数等 这些DSP函数支持不同的数据类型 包括float double fract16等 库文件位置 安装目录 Blackfin lib BF533调用的是libdsp532 dlb头文件位置 安装目录 Blackfin includes 源代码位置 安装目录 Blackfin lib src libdsp 可根据需要对源代码进行修改 请将文件复制到其它地方 重命名后再进行修改 调用库文件时需要先引用相应的头文件 25 Libdsp提供的库函数 comples h基本复数运算 包含各类复数类型 如complex float complex fract16 变量的定义和基本数学操作 例如复数绝对值 复数加减法 复数乘除法 获取复数相位 共轭 归一化等filter h滤波和变换滤波包括FIR IIR 直接I型IIR 抽取 内插FIR 复数FIR等等变换FFT 获得FFT旋转因子 IFFT R4 FFT等卷积卷积操作 二维卷积 3 3矩阵的二维卷积等压缩 扩展的相关函数包括A律 u律压缩 扩展math h数学函数 例如求绝对值 指数 对数 幂运算 三角运算 最大值 最小值 平方根等 matrix h矩阵函数 如实数 复数矩阵加 减 乘一个标量 矩阵转置等stats h统计函数 包括自相关 互相关 柱状图 均值 方差 过零点等vector h向量函数 包含实数与复数的向量操作 例如点积 向量加 减 乘一个标量 向量中的最大 最小元素及各自的索引等 window h滤波 谱分析加窗时的窗函数 包括Gaussian窗 Hamming窗 Kaiser窗 三角窗等 使用时参考VisualDSP 4 5C C CompilerandLibraryManualforBlackfinProcessors pdf 26 数字滤波的实现 滤波及频谱分析可以采用ADI提供的滤波器库函数 DSPrun timelibrary中的库函数 需要包含filter h 滤波器及变换的头文件 即 include 滤波器初始化fir init state coefs delay NUM TAPS 1 其中state为初始状态 coefs为滤波器系数 delay为线性缓冲区的首地址 NUM TAPS为滤波器阶数 最后一个参数表示是否内插或抽取 interpolation decimationindex 事实上 fir init就是一个宏 即 definefir init state coeffs delay ncoeffs index state h coeffs state d delay state p delay state k ncoeffs state l index 27 对输入信号进行滤波fir fr16 in out VEC SIZE 获得 源代码可以在 安装目录下 Blackfin lib src libdsp 找到fir fr16 asm 28 输入信号产生与引入 实验中输入的信号可以事先由Matlab编程获得fid fopen signal dat w fprintf fid 0 x 04x n x1 fclose fid 使用时在DSP程序中采用fract16in 256 include signal dat 也可以在DSP程序中编程得到信号 include include out fract16 0 5 sin 2 PI f step 32768 0 加噪声 include out fract16 rand 0 x20000000 15 29 频谱分析的实现 计算旋转因子voidInit FFT void 需包含 include twidfftrad2 fr16 fft twid VECTOR SIZE 获取循环缓冲区的指针 需包含 include counter builtin circindex counter INPUT SIZE current size 给信号加窗 需包含 include fft in i mult fr1x16 win bart i input arr i FFT计算 需包含 include rfft fr16 fft in fft temp fft out fft twid int VECTOR SIZE current size current size 1 1 计算FFT的幅度谱 需包含 include for i 0 i current size i fft mag i cabs fr16 fft out i fft mag i sqrt fft out i re fft out i re fft out i im fft out i im 30 Circularaddressing A i n Thecompilernowattemptstotreatarrayreferencesoftheformarray i n ascircularbufferoperations force circbufcanhelpthecompilertoacceptthesafetyofacircularbufferaccess Explicitcircularaddressingofanarrayindex longcircindex longindex longincr unsignedlongnitems Explicitcircularaddressingonapointer void circptr void ptr longincr void base unsignedlongbuflen 31 设备驱动库函数 drivers adi dev h drivers adi uart h services services h 32 采用设备驱动这种方式 使应用程序不用考虑控制硬件设备的细节 对应用程序而言 设备的控制与正常的调用函数没有什么不同 设备驱动程序位于系统服务程序的上方 设备驱动程序将调用系统服务程序 如中断 设备驱动库是ADI提供的部分器件的设备驱动程序集合 如果在系统中使用的是设备驱动库中的设备 则对BlackfinDSP来说直接调用设备驱动库中相应的文件和函数即可 如果使用的设备不在设备驱动库中 也可以参照ADI的同类型器件的设备驱动程序来编写所用设备的驱动程序 使用时需要包含 include 系统服务程序 include 设备管理器 include UART驱动程序 33 include 系统服务程序包括了所有的系统服务程序 如DMA 中断 接口控制等服务程序 include 设备管理器包括了所有关于设备驱动程序的一般信息 如API 返回码 事件代码即所有的设备驱动程序一般信息 include xxx设备的驱动程序特定的设备的驱动程序的包含文件 应当包含设备驱动程序本身 相关文件所在位置如下 头文件在安装目录下Blackfin include drivers或services文件夹中各个驱动程序的源代码在安装目录下Blackfin lib src drivers或services文件夹中库文件在安装目录下Blackfin lib文件夹中 34 设备管理 adi dev hadi dev Open Opensadeviceforuseadi dev Close Closesdownadeviceadi dev Read Providesadevicewithbuffersforinbounddataadi dev Write Providesadevicewithbuffersforoutbounddataadi dev Control Sets detectscontrolandstatusparametersforadevice 35 系统服务 SystemInterruptControllerFunctions adi int SICEnable EnablesperipheralinterruptstobepassedtotheCECadi int SICDisable DisablesperipheralinterruptsfrombeingpassedtotheCECadi int SICSetIVG SetstheIVGleveltowhichaperipheralinterruptismappedadi int SICGetIVG DetectstheIVGleveltowhichaperipheralinterruptismappedadi int SICWakeup Establisheswhetherornotaperipheralinterruptwakesuptheprocessorfromanidledstateadi int SICInterruptAsserted Detectswhetherornotaperipheralinterruptisasserted 36 不同的开发板都有相应的驱动库的使用示例程序供参阅 位置在 AnalogDevices VisualDSP4 5 Blackfin Examples ADSP BF533EZ KitLite Drivers关于系统服务的示例程序 位置在 AnalogDevices VisualDSP4 5 Blackfin Examples ADSP BF533EZ KitLite Services外设驱动相关的文档在 AnalogDevices VisualDSP4 5 Blackfin docs drivers中关于系统服务及设备驱动请参考 VisualDSP 4 5DeviceDriversandSystemServicesManualforBlackfinProcessors pdf 37 C与汇编混合编程用C语言编程结构化程度高 易于编写 但执行速度相对较慢 与之相反 汇编程序速度快 但很难有较好的结构 且编写起来耗时 不易调试 C和汇编混合编程结合了各自的优势 往往能构造出结构化好且执行速度快的程序 C和汇编混合编程 通常有两种基本方法 一是C代码中内嵌汇编代码 二是C代码中调用汇编语言写的子函数 在第一种方法中 采用C的库函数asm 内嵌代码 这比较简单 但不常用 第二种方法为常用的混合编程方法 通常在优化代码时使用 但这种方法比前一种复杂 38 C调用汇编 要命名一个与C C 标识符对应的汇编标识符 当在汇编程序中使用它们时在C C 标识符前加下划线 在汇编程序和C C 中公用 相互调用 的函数或变量 需要在汇编程序中用 GLOBAL伪指令声明该标识符 然后通过在C C 程序中将该标识符声明为extern型将其导出 C调用汇编函数时 前三个参数依次传给R0 R1 R2 多于三个参数时 多出的参数依次压入堆栈 返回时 返回值小于或等于32位用R0返回 入大于32位且小于等于64位 使用R0 R1返回 39 BlackfinC编程注意事项 如果在多个C文件中使用同一个符号 在符号的定义文件中定义为全局 然后在头文件中使用extern将其导出 使用时包含该头文件 这样就可以直接使用这个符号了 BF533片内外设寄存器 MMR寄存器 的地址定义在cdefBF53x h中 实际在cdefBF532 h中 使用外设时应该包含该文件 即 include如果需要使用BF533的MMRs寄存器的一些预设值 即一些寄存器中的位的位定义 例如DI EN MDSIZE 8等宏定义 需要包含defBF532 h如果需要使用内置的系统服务函数 例如ssync sysreg read 则需要包含ccblkfn h 40 def LPBlackfin h定义内核MMRs寄存器 例如核定时器 中断寄存器 状态寄存器 配置寄存器等 的地址及其位定义 需要使用内核寄存器时需要包含该文件注意 cdefBF53x h文件中已经包含了defBF532 h ccblkfn h def LPBlackfin h等 所以如果文件中已经包含了cdefBF53x h这个头文件 就不必再包含defBF532 h ccblkfn h def LPBlackfin h等其它头文件了 41 sysreg h中有访问系统寄存器 即外设寄存器 的寄存器名字的定义 例如reg CYCLES 可以通过sysreg read sysreg write等这些系统函数来访问 使用sysreg h时需要使用ccblkfn h头文件 一般sysreg h和ccblkfn h这两个头文件一起出现 即 include includeexception h中包含了关于中断 异常的寄存器的宏定义 中断矢量表 中断类型定义 中断信息定义等 若使用EX INTERRUPT HANDLER register handler 等这些宏 需要包含头文件exception h 即 include 42 如果用户自己开发了扩展板 或使用CPLD 需要为一些外围设备分配地址 选通地址 芯片内的内部寄存器地址等 则需要编写一个用户自己的头文件来定义这些地址 例如北京迪码公司的SSK板就采用了dm bf5xx h来定义板上的资源 如需要使用SSK板上的资源 则需要在文件头包含dm bf5xx h文件 即 include exception h 一般习惯把所需要包含的所有头文件 以及一些全局变量 常量 函数声明等都放在一个头文件里面 这样只需要在应用程序中包含这一个头文件就可以了 一般先使用idle 再使用ssync 使系统进入空闲模式 一般先访问MMRs 然

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论