您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 总结/报告 > DSP程序在线升级报告(本人觉得最给力的资料)
DSP程序在线升级唐俊松tangjunsong@zju.edu.cn2015/12/041.引言一般而言,DSP程序更新是在CCS环境下通过JTAG接口来实现的。但JTAG烧写程序只能实现一对一烧写(即电脑到DSP),且不能远距离烧写程序。而当产品发布后或需要同时升级多个DSP程序时,通过JTAG烧写程序则很难实现。在线程序升级的主要思想是通过串口通信更新程序,通过串口通信可实现程序远程升级且可同时实现对多个DSP的程序更新,这有效地解决了JTAG烧写程序所存在的弊端。DSPJTAGPC上位机DSPDSP………DSP………RS2321.通过JTAG更新DSP程序2.通过串口(RS232)更新DSP程序图1.1通过不同方式实现DSP程序更新2.程序在线升级的基本思想基于串口通信的程序在线升级功能框图如图2.1所示,底层程序(ProgLocal)和应用程序(ProgApp)分别由两个独立的CCSProject产生。底层程序(ProgLocal)是产品发布前通过JTAG烧写固化在DSP指定Flash空间中的程序,不允许用户修改和擦除,主要用于实现与上位机的通信,同时在需要升级程序时将上位机发送过来的程序代码烧写到FLASH中。应用程序(ProgApp)是可以更新的程序。通过CCS编译产生程序代码文件(hex),然后通过RS232通信将程序代码发送到DSP,继而由底层程序(ProgLocal)将应用程序代码烧写到应用程序所对应FLSH空间(ProgApp)中。ProgLocalProgAppCCSProjectADSPRS232上位机(HMIS)Hex文件CCSProjectLJTAG图2.1DSP程序在线升级功能框图在线升级程序流程图如图2.2所示。DSP上电复位后先运行底层程序,在底层程序中判断是否需要升级,如不需要升级,则跳转到应用程序执行。如需要升级,则擦除应用程序对应FLASH区,并将升级代码写入到应用程序FLASH区中。Begin底层程序是否升级?接收升级程序代码将升级程序代码烧写到Flash应用程序是否跳转End与上位机通信图2.2DSP程序更新流程图3.在线程序升级的具体实现3.1FLASH分配要实现程序在线升级,必须使底层程序和应用程序相互独立。如图2.1所示,本项目将底层程序(LocalProgram)配置在FLASHA中,应用程序(ApplicationProgram)配置在FLASHE中,从而实现底层程序与应用程序的独立。实现程序相互独立需通过配置cmd文件完成,具体配置方法见附录1。LocalProgram(FLASHA)ApplicationProgram(FLASHE)DSP图3.1DSPFLASH分区示意图3.2应用程序更新代码产生需要更新的应用程序代码是通过CCSProjectA编译产生的,但CCS编译生成的是具有模块化格式的目标文件(.out文件),该文件中的代码和数据分别存放在不同的段中,因而不能直接用来烧写Flash,需将其转换为能识别的数据格式(hex文件)(hex数据文件格式详见附录4)。生成hex文件后,通过上位机读取hex文件数据,并将数据通过RS232通信发送至DSP。CCS自带工具hex2000.exe可实现.out文件到.hex文件的转换。(转换方法见附录6)CCSProjectAA.outA.hexDSPRS232编译Hex2000图3.2应用程序代码产生方法3.3底层程序(LocalProg)底层程序主要实现两个功能:(1)与上位机通信;(2)升级时,将串口接收到的数据烧写至Flash的指定区域。底层程序主要实现以下功能,其流程图如右图所示:(1)与上位机通信,判断是否升级DSP上电复位后与上位机通信,判断是否需要升级。若上位机发送的是升级命令,则跳转到底层程序中升级部分执行;否则,跳转到原有的应用程序处执行。(2)从上位机接受程序代码并校验接收上位机发送的应用程序代码并保存到DSP指定内存中(RAM区),(如何将数据保存到指定内存,详见附录2)。与此同时,需校验接收数据是否准确。(3)烧写程序的搬移由于DSP不支持对FLASH烧写的同时在FLASH中运行程序,因此负责烧写Flash的这部分程序应搬移至片内RAM执行。(如何实现程序搬移,详见附录3)(4)烧写程序代码搬移结束后,将之前RAM中接受到的程序代码烧写至指定Flash扇区,该步骤通过调用Flash28335_API库函数完成(Flash28335_API的使用请看附件中FLASH_API文档)。DSP上电复位“JumptoFlash”与上位机建立联系?判断是否升级Y跳转到原有的应用程序执行NN通过串口接收上位机发送的更新代码到片内RAM代码接收完毕?调用FLASH28335_API库函数进行FLASH程序烧写烧写完毕校验烧写是否正确烧写结束,等待系统重新复位YYN4.总结实现程序在线升级的主要难点是如何实现底层程序和应用程序相互独立,以及如何通过CCS产生需要更新的应用代码。本报告首先介绍了DSP程序在线升级的主要思想,然后对程序在线升级的实现方法作了简单介绍,并在附录中给出了具体实现过程中可能会遇到的问题及解决办法。附录1底层程序和应用程序cmd配置要实现如图4.1所示的FLASH分配,须通过配置底层程序和应用程序cmd文件完成。其中底层程序对应CCSProjectL,配置其cmd文件使其程序分配在FLASHA区;应用程序对应CCSProjectA,配置其cmd文件使其程序分配在FLASHE区。LocalProgram(FLASHA)ApplicationProgram(FLASHE)DSP图4.1DSPFLASH分区示意图1.1底层程序cmd配置DSPF28335上电复位后,当硬件配置为FLASH启动时,程序指针将跳转到Flash的0x33FFF6处(F28335启动过程,详见附录5)。由于这个地址是固定的,因此底层程序必须烧写在以这个地址为起始地址的空间内,即底层程序cmd配置应为:MEMORY{PAGE0:BEGIN:origin=0x33FFF6,length=0x000002/*BoottoFLASHwillgohere*/...}SECTIONS{...codestart:BEGINPAGE=0...}与此同时,底层程序所有程序代码段应全部烧写到FLASHA中:MEMORY{PAGE0:FLASHA:origin=0x338000,length=0x007F80/*on-chipFLASH*/...}SECTIONS{....cinit:FLASHAPAGE=0.pinit:FLASHA,PAGE=0.text:FLASHAPAGE=0...}1.2应用程序cmd配置采用绝对地址跳转实现由底层程序到应用程序的跳转,为保证程序正常执行,其跳转地址必须固定,且该地址在应用程序中的位置必须固定。将应用程序的首地址作为跳转地址,即跳转地址固定为FLASHE的起始地址:0x318000,如图4.2所示。ApplicationProgram(FLASHE)CodeStart图4.2应用程序FLASH示意图采用绝对地址跳转实现从底层程序跳转到应用程序。跳转指令为:#defineJump_App_Program(void(*)(void))0x318000/*usetheFlashEsectortosavetheapplicationprogram*/(*Jump_App_Program)();/*Jumptotheapplicationprogram*/同时应配置ProgApp的程序起始地址为从(FLASHE)起始地址0x318000开始,对应CMD配置为:MEMORY{PAGE0:BEGIN:origin=0x318000,length=0x000002/*0x318000isthestartaddressofFLASHE*/...}SECTIONS{...codestart:BEGINPAGE=0/*codestartisthestartaddressoftheprogram*/...}与此同时,底层程序所有程序代码段应全部烧写到FLASHE中:MEMORY{PAGE0:FLASHE:origin=0x318002,length=0x007F80/*on-chipFLASH*/...}SECTIONS{....cinit:FLASHEPAGE=0.pinit:FLASHE,PAGE=0.text:FLASHEPAGE=0...}附录2:如何将程序和变量放到指定位置在CCS编程中,如果我们不指定变量的存放位置,编译器会自动的给变量分配一个位置,但是如果有时候需要把变量放在一个特定的空间内,我们应该如何操作呢,CCS提供了如下的两个指令:#pragmaCODE_SECTION#pragmaDATA_SECTION其中DATA_SECTION是针对数据空间的,CODE_SECTION是针对程序空间的,具体的使用办法是:#pragmaDATA_SECTION(buffer,”DATA_sect”)charbuffer[512];//buffer为一数组#pragmaCODE_SECTION(fun,”CODE_sect”)Intfun();//fun为任意函数与此同时,在CMD文件中为DATA_sect、CODE_sect开辟空间:DATA_sect:RAML2PAGE=1CODE_sec:FLASHEPAGE=0附录3:如何将FALSH中程序搬移到RAM中运行CCS中经常会遇到如下语句:MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart)它的作用是将ramfuncs段复制到内存中然后运行。CMD文件中ramfuncs的定义如下;ramfuncs:LOAD=FLASHD,RUN=RAML0,LOAD_START(_RamfuncsLoadStart),LOAD_END(_RamfuncsLoadEnd),RUN_START(_RamfuncsRunStart),PAGE=0第1行表示该段的装载在PAGA0的FLASHD中第2行表示该段的运行地址在PAGE0的RAML0中LOAD_START(_RamfuncsLoadStart)令编译器创建了一个变量RamfuncsLoadStart,该变量指向段ramfuncs的装载地址的首地址(LOAD_START为编译伪指令,请见CCS的帮助文档);LOAD_START(_RamfuncsLoadEnd)令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址(LOAD_END为编译伪指令,请见CCS的帮助文档);LOAD_START(_RamfuncsRunStart)令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址(LOAD_START为编译伪指令,请见CCS的帮助文档);从第1和2行可以看出,段ramfuncs中的函数DSP28x_usDelay()的装载地址和运行地址是不同的,本程序中装载在Flash的块FLASHD中,而在SARAML0中运行,这只是目标,实际运行时DSP并不会自动将Flash中的代码拷贝到SARAM中,因此需要手动添加代码来完成。在C函数中,为了使用变量RamfuncsLoadStart、RamfuncsLoadEnd和RamfuncsRunStart,必须先声明,本工程在文件DSP2833x_GlobalPrototypes.h中做了如下声明:externUint16RamfuncsLoadStart;externUint16RamfuncsLoadEnd;externUint16RamfuncsRunStart;然后就可以使用了。在Main.c中,使用MemCopy()函数将段ramfuncs中的函数DSP28x_usDelay()的代码从装载地
本文标题:DSP程序在线升级报告(本人觉得最给力的资料)
链接地址:https://www.777doc.com/doc-1557722 .html