[经验] DSP外扩SRAM的应用测试心得体会

fish001   2017-10-22 21:40 楼主
DSP的硬件测试说明: 平台说明: 360截图20171022214957995.jpg 图1-1 Code Composer Studio 6.0.0.00190 C/C++开发环境 硬件平台基于TMS320F28335芯片,软件平台基于TI的Code Composer Studio 6.0.0.00190 C/C++开发环境,如图1-1所示。 工作进度说明: 1.完成了DSP外扩SRAM的硬件的完整测试,通过修改TI官方的.cmd文件和库函数调用, 可以将FLASH中的函数复制到外部SRAM中运行,大大提高DSP程序的运行速度,附有详细说明。 2. 完成了RS485的驱动编写及应用测试。 3.利用官方的ADC_DMA、I2C例程,完成ADC和EEPROM的测试,整合了ADC_DMA例程。 4.CAN通讯和转速中断的代码公司已有,未整理。 5.DSP内置的看门狗模块已开启。 一、DSP扩展的外部SRAM应用说明(已测试完毕) 前言: DSP可以工作中150MHz的频率下,为了发挥其高速运行的特性, 一般会将 FLASH程序内容复制到外部高速SRAM中运行,TMS320F28335内部有34K X 16bit的SRAM, TI将内部SRAM分成了多块(见F28335.cmd)。 一般的程序在内置FLASH中运行,程序在FLASH中的运行速度由FLASH的读取速度决定, 如果没有采用FLASH的加速技术,一般需要设置等待时间。 要想使程序高速运转, 最少要扩展一块SRAM 来高速运行DSP算法或中断函数。 1.外部SRAM分区说明 本项目的硬件扩展了256K 16bit SRAM 时钟延迟为10ns SRAM型号为: IS61LV25616AL-10T 定位地址为: 0x0200000 前128K 用作程序空间,后128K用作数据空间 定位地址和ARM的内部SRAM地址一样,DSP中文数据手册参考内容如下图所示(可放大): 360截图20171022214346633.jpg 图1-2 DSP典型的16位和32位数据总线连接示意图 IS61LV25616AL-10T芯片的数据总线是16位,后面的STM32F429板子也用了这个芯片,但增加了高低位选通线, 因此可以读高低字节,比DSP更灵活:DSP最少一次读2字节,ARM想读任何字节都可以。另外ARM内部有FLASH加速, 可以直接跑180MHz,外设是90MHz,但比DSP性能相差已经比较小了。 DSP的GPIO37/XZCS7引脚控制的外部SRAM的物理地址如下图所示: 360截图20171022214418396.jpg 图1-3 GPIO37/XZCS7引脚控制的外部SRAM的物理地址说明 在F28335.CMD文件分配,详细内容如下: XINTF zone 7 - program space ZONE7A : origin = 0x0200000, length = 0x020000 XINTF zone 7 - data space ZONE7B : origin = 0x0220000, length = 0x020000 2.外部DATA SRAM使用说明 内部SRAM不够用,则使用外部DATA SRAM,用法如下 #pragma DATA_SECTION(bufferB, "ZONE7DATA"); uint16_t bufferB[512]; 仿真测试结果: 观察数据0x22000区域,可以看到bufferB区域被程序设置了正确的数据。 2.外部CODE SRAM使用说明 外部中断函数或一般函数使用如下格式的声明 #pragma CODE_SECTION(cpu_timer0_isr,"xintffuncs"); #pragma CODE_SECTION(cpu_timer1_isr,"xintffuncs"); 编译器会将这些特定的函数分配在一个固定的FLASH区域 起始地址为XintffuncsLoadStart 结束地址为XintffuncsLoadEnd 主程序中XINTF Zone 7初始化后,调用如下函数将这个区域的特定函数 复制到外部SRAM的运行程序空间(0x0200000-0x021FFFF) MemCopy(&XintffuncsLoadStart, &XintffuncsLoadEnd, &XintffuncsRunStart); 频繁运行或调用的捕获函数、定时器函数或特定算法,只有在高速SRAM中运行, 才能真正发挥TMS320C28335的实际性能。 仿真测试结果: cpu_timer0_isr和cpu_timer1_isr定位在0x200000-0x21FFFF区域 对这两个中断函数设置断点,可以正常进入中断运行。 定时器0中断函数的实际仿真结果如下图所示: 360截图20171022214515497.jpg 360截图20171022214523583.jpg 图1-4 定时器0中断函数的加载到外部SRAM前后对比分析图 定时器1中断函数的实际断点仿真如下(是无损压缩图片,可以放大): 360截图20171022214605296.jpg 图1-5 定时器1中断代码的运行地址分析 可以得出结论,在反汇编窗口,看到定时器1中断的入口地址是0x2002a,在1ms的定时器1中断内翻转GPIO50脚,产生一个方波。 360截图20171022214637166.jpg 图1-6 定时器1中断的应用测试截图 该图比较小,是因为用的是小示波器保存到U盘的图片。用该示波器保存成csv格式,仅有2500个数据。 录波仪录制数据波形比较长,十几秒就可以存下超过100万个点的数据,当然普通的.xls或.xlsx文件是存不下的。 二、通信配置说明(进行中) 1. RS485通信配置和应用测试代码 以下是网络参考代码,实际的配置比较繁琐,这里简略不写了。 // 重新映射 PIE - Timer 0的中断
  • EALLOW; // 解除寄存器保护
  • PieVectTable.TXBINT = &SCI_TX_isr;
  • PieVectTable.RXBINT = &SCI_RX_isr;
  • EDIS; // 使能寄存器保护
  • // 使能接收中断
  • PieCtrlRegs.PIEIER8.bit.INTx3 = 1;
  • // 使能发送中断
  • // PieCtrlRegs.PIEIER9.bit.INTx4 = 1;
  • IER |= 0x100;
  • // 全局中断使能和更高优先级的实时调试事件
  • EINT; // 全局中断使能INTM
  • ERTM; // 使能实时调试中断DBGM
SCIC串口发送和接收的大致流程如图1-6所示。 360截图20171022214706226.jpg 图1-7 SCIC串口的发送和接收流程 // 利用TMS320F28335的SCIC串口FIFO来发送数据,只要数据包不超过16, // 都可以无需等待,直接将所有字节放入FIFO,极大的节约CPU的时间开销 // 具体实现如下,至于官方的例程,等待当前字节发送完毕再发下一个, // 这样太浪费时间,在实际产品中基本上没人用 if(Flag_CpuTimer0){ Flag_CpuTimer0 = 0; // 10ms 定时周期 GpioDataRegs.GPBSET.bit.GPIO50 = 1; // RS485 DE = 1 RS485切换为发送状态 for(i = 0; i < 10; ++i){ ScicRegs.SCITXBUF = bufferA; // 将10个数据放入FIFO,然后自动依次转移到移位寄存器 } asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); } // RS485处于发送状态,且SCIC移位寄存器为空 if((GpioDataRegs.GPBDAT.bit.GPIO50 == 1)&&(ScicRegs.SCICTL2.bit.TXEMPTY == 1)){ GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1; // RS485 DE = 0 RS485转为接收状态 } 2. CAN通信配置 进行中 三、数据存储器配置说明(I2C) 扩展了512K byte EEPROM,打开官方的I2C例程(非GPIO模拟的时序),已测试OK。 四、集成功率芯片测试(GPIO) 主要是对功率器件的测试,进行中 五、看门狗配置说明(已完成) 一般嵌入式系统都需要开启外部或内部看门狗,以防意外的CPU挂起死机 六、TI官方的CMD文件说明(实际应用的文件是在官方的基础上稍作修改) TI官方提供的CMD文件有三个: 28335_RAM_lnk.cmd、F28335.cmd、DSP2833x_Headers_nonBIOS.cmd 调试程序时,将28335_RAM_lnk.cmd文件加入工程中,程序被加载到SRAM中运行。 实际的产品运行时,需要将程序下载到FLASH中,并从FLASH中启动,这时需要 在工程中加入F28335.cmd文件,同时屏蔽28335_RAM_lnk.cmd文件。 TI官方文件F28335.cmd对内部SRAM的分配如下: BOOT_RSVD : origin = 0x000000, length = 0x000050 // Part of M0, BOOT rom will use this for stack PAGE 1 RAMM0 : origin = 0x000050, length = 0x0003B0 // on-chip RAM block M0 PAGE 1 RAMM1 : origin = 0x000400, length = 0x000400 // on-chip RAM block M1 PAGE 1 ZONE0 : origin = 0x004000, length = 0x001000 // XINTF zone 0 PAGE 0 RAML0 : origin = 0x008000, length = 0x001000 // on-chip RAM block L0 PAGE 0 RAML1 : origin = 0x009000, length = 0x001000 // on-chip RAM block L1 PAGE 0 RAML2 : origin = 0x00A000, length = 0x001000 // on-chip RAM block L2 PAGE 0 RAML3 : origin = 0x00B000, length = 0x001000 // on-chip RAM block L3 PAGE 0 RAML4 : origin = 0x00C000, length = 0x001000 // on-chip RAM block L1 PAGE 1 RAML5 : origin = 0x00D000, length = 0x001000 // on-chip RAM block L1 PAGE 1 RAML6 : origin = 0x00E000, length = 0x001000 // on-chip RAM block L1 PAGE 1 RAML7 : origin = 0x00F000, length = 0x001000 // on-chip RAM block L1 PAGE 1 Allocate DMA-accessible RAM sections: DMARAML4 : > RAML4, PAGE = 1 DMARAML5 : > RAML5, PAGE = 1 DMARAML6 : > RAML6, PAGE = 1 DMARAML7 : > RAML7, PAGE = 1 Allocate uninitalized data sections: .stack : > RAMM1 PAGE = 1 .ebss : > RAML4 PAGE = 1 .esysmem : > RAMM1 PAGE = 1 TI官方文件DSP2833x_Headers_nonBIOS.cmd对特殊功能寄存器的映射(PAGE 1)如下 DEV_EMU : origin = 0x000880, length = 0x000180 // device emulation registers FLASH_REGS : origin = 0x000A80, length = 0x000060 // FLASH registers CSM : origin = 0x000AE0, length = 0x000010 // code security module registers ADC_MIRROR : origin = 0x000B00, length = 0x000010 // ADC Results register mirror XINTF : origin = 0x000B20, length = 0x000020 // external interface registers CPU_TIMER0 : origin = 0x000C00, length = 0x000008 // CPU Timer0 registers CPU_TIMER1 : origin = 0x000C08, length = 0x000008 // CPU Timer0 registers (CPU Timer1 & Timer2 reserved TI use) CPU_TIMER2 : origin = 0x000C10, length = 0x000008 // CPU Timer0 registers (CPU Timer1 & Timer2 reserved TI use) PIE_CTRL : origin = 0x000CE0, length = 0x000020 // PIE control registers PIE_VECT : origin = 0x000D00, length = 0x000100 // PIE Vector Table DMA : origin = 0x001000, length = 0x000200 // DMA registers MCBSPA : origin = 0x005000, length = 0x000040 // McBSP-A registers MCBSPB : origin = 0x005040, length = 0x000040 // McBSP-B registers ECANA : origin = 0x006000, length = 0x000040 // eCAN-A control and status registers ECANA_LAM : origin = 0x006040, length = 0x000040 // eCAN-A local acceptance masks ECANA_MOTS : origin = 0x006080, length = 0x000040 // eCAN-A message object time stamps ECANA_MOTO : origin = 0x0060C0, length = 0x000040 // eCAN-A object time-out registers ECANA_MBOX : origin = 0x006100, length = 0x000100 // eCAN-A mailboxes ECANB : origin = 0x006200, length = 0x000040 // eCAN-B control and status registers ECANB_LAM : origin = 0x006240, length = 0x000040 // eCAN-B local acceptance masks ECANB_MOTS : origin = 0x006280, length = 0x000040 // eCAN-B message object time stamps ECANB_MOTO : origin = 0x0062C0, length = 0x000040 // eCAN-B object time-out registers ECANB_MBOX : origin = 0x006300, length = 0x000100 // eCAN-B mailboxes EPWM1 : origin = 0x006800, length = 0x000022 // Enhanced PWM 1 registers EPWM2 : origin = 0x006840, length = 0x000022 // Enhanced PWM 2 registers EPWM3 : origin = 0x006880, length = 0x000022 // Enhanced PWM 3 registers EPWM4 : origin = 0x0068C0, length = 0x000022 // Enhanced PWM 4 registers EPWM5 : origin = 0x006900, length = 0x000022 // Enhanced PWM 5 registers EPWM6 : origin = 0x006940, length = 0x000022 // Enhanced PWM 6 registers ECAP1 : origin = 0x006A00, length = 0x000020 // Enhanced Capture 1 registers ECAP2 : origin = 0x006A20, length = 0x000020 // Enhanced Capture 2 registers ECAP3 : origin = 0x006A40, length = 0x000020 // Enhanced Capture 3 registers ECAP4 : origin = 0x006A60, length = 0x000020 // Enhanced Capture 4 registers ECAP5 : origin = 0x006A80, length = 0x000020 // Enhanced Capture 5 registers ECAP6 : origin = 0x006AA0, length = 0x000020 // Enhanced Capture 6 registers EQEP1 : origin = 0x006B00, length = 0x000040 // Enhanced QEP 1 registers EQEP2 : origin = 0x006B40, length = 0x000040 // Enhanced QEP 2 registers GPIOCTRL : origin = 0x006F80, length = 0x000040 // GPIO control registers GPIODAT : origin = 0x006FC0, length = 0x000020 // GPIO data registers GPIOINT : origin = 0x006FE0, length = 0x000020 // GPIO interrupt/LPM registers SYSTEM : origin = 0x007010, length = 0x000020 // System control registers SPIA : origin = 0x007040, length = 0x000010 // SPI-A registers SCIA : origin = 0x007050, length = 0x000010 // SCI-A registers XINTRUPT : origin = 0x007070, length = 0x000010 // external interrupt registers ADC : origin = 0x007100, length = 0x000020 // ADC registers SCIB : origin = 0x007750, length = 0x000010 // SCI-B registers SCIC : origin = 0x007770, length = 0x000010 // SCI-C registers I2CA : origin = 0x007900, length = 0x000040 // I2C-A registers CSM_PWL : origin = 0x33FFF8, length = 0x000008 // Part of FLASHA. CSM password locations PARTID : origin = 0x380090, length = 0x000001 // Part ID register location 本帖最后由 fish001 于 2017-10-22 22:02 编辑
  • 360截图20171022214223310.jpg

回复评论 (1)

点赞  2017-11-1 20:37
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复