本发明涉及一种基于CAN通信的DSP在线升级方法。
背景技术:
目前DSP程序烧写有以下几种方式:
仿真器烧写程序:首先将仿真器与DSP的JTAG接口相连,同时与安装有仿真器驱动程序及CCS应用软件的电脑相连。然而此种方式的嵌入式设备在密闭的箱体内JTAG口不方便连接,于是会给升级带来了极大的不便,而且程序烧写速度有限导致通信速度受限,不能满足用户需求。
通过目标板上的拨码开关选择芯片引导程序,采用SPI\SCI串口等通讯方式下载程序。由于这种方式需进行拨码开关选择,均需对目标板进行操作,控制器一旦封盖也就不再方便用户进行程序升级,所以也不是程序烧写的最佳方式。
以上所述烧写方式一般都存在一些共性问题:烧写速度有限导致程序升级时间较长;嵌入式设备一般都会封闭在箱体内,这会给升级带来不便;程序烧写过程复杂,用户需要将.out文件通过文件转换工具根据.cmd文件转换成.hex文件才能进行烧写。因此基于上述问题,有必要针对DSP嵌入式设备升级所需进行的可扩展程序烧写的方法做进一步的改进和完善,以适应嵌入式系统在软件控制领域的在线升级功能。
技术实现要素:
本发明的目的是为了解决现有技术中存在的缺陷,提供一种能提高对目标板进行在线升级和程序替换效率和速度的方法。
为了达到上述目的,本发明提供了一种DSP芯片在线升级方法,该升级方法通过CAN通讯总线对各节点的DSP芯片进行在线程序升级;DSP芯片为嵌入有CAN总线控制模块的芯片,如TMS320F2833x系列的DSP芯片。
本发明DSP芯片在线升级方法具体包括以下步骤:
S1:打开上位机软件,设置好必要配置,进行COFF文件解析;
S2:使用CAN通信方式连接DSP芯片与上位机,给DSP芯片上电复位并启动CAN通讯模块;
S3:DSP拨码开关均上拉,保持默认从FLASH启动,程序运行到主函数入口地址处;
S4:开始启动二次boot程序,延时等待约5s,若超时,直接跳转进入S8;利用仿真器,所述二次boot程序为利用仿真器在DSP上烧写固化的一个核程序,用来获取CAN总线的控制权,完成FLASH_API程序升级操作;
S5:上位机在5s内发送boot升级命令,若命令正确,则进入S6,若受到干扰或命令错误,则跳转到S2;
S6: 上位机应用程序下载模块启动,通过CAN通信与DSP建立连接,进行用户程序升级过程:将S1中解析后提取的COFF文件中的段数据,通过CAN通讯分包将其发送至下位机DSP芯片,更新FLASH中用户程序,完成加载用户程序升级;
S7:跳转到用户程序入口地址,进入S8;
S8:执行用户程序,完成boot升级功能。
其中,步骤S1中COFF文件解析过程包括:
a1、在CCS上根据cmd文件内存分配要求编写用户升级程序,然后编译链接生成最终可执行的用户程序.out文件,即COFF文件;
b1.上位机直接加载用户程序.out文件进行解析,将解析完数据存放入缓存区和相应的变量中,生成一个扩展名为.sc文件进行保存;
c1.使用TI工具dis2000.exe对.out文件进行反汇编,与上位机解析出的数据进行对比,确保上位机解析正确;
d1.提取COFF文件中对应的段数据。
上述步骤b1中上位机直接加载用户程序.out文件进行解析的过程为:
首先分析.out文件的文件头以确定有多少个段,然后逐段分析段信息头,根据段属性标识以确定是否需要下载,段头中的绝对地址、段数据长度等信息作为升级文件的一部分,与需下载的段数据合并成最终的下载文件,最后以.sc文件的形式保存所有解析得到的数据信息;所述步骤d1中提取COFF文件中的段数据与步骤b1解析过程中确定需下载的段数据进行对应,一般为初始化数据段,不包含未初始化数据段。
上述步骤S6中通过CAN通信启动用户程序升级过程为:
a6、DSP芯片通过CAN总线接收上位机发送的擦除命令,擦除用户程序所需固化的FLASH扇区,成功擦除后反馈信息告诉上位机擦除成功;
b6、DSP芯片通过CAN总线接收上位机发送的写命令,然后上位机将S1中解析后提取的用户程序COFF文件中的段数据,通过CAN通讯分包将其发送至下位机DSP芯片,DSP芯片再根据.cmd内存分配方式合理分配用户程序各段在FLASH中的存储空间,然后执行写操作将用户程序按数据段组包依次写入FLASH对应扇区,写成功后反馈信息告诉上位机FLASH写入成功;
c6、DSP芯片通过CAN总线接收上位机发送的退出命令,指示DSP编程操作完成,不用返回给上位机任何信息,直接退出BootLoader程序。
步骤b6中通过CAN通讯分包发送的方式为:通过三次探测,下位机进行COFF文件数据段下载;
第一次探测:首先给DSP芯片发送一个数据‘A’进行握手,握手成功后则继续给DSP芯片发送一个文件报文数据进行传输通讯测试,成功测试后反馈一个探测成功信息,否则反馈一个失败信息;
第二次探测:首先给DSP芯片发送一个数据‘A’进行握手,握手成功后则继续给DSP芯片发送另一个文件报文数据进行传输通讯测试,成功测试后反馈一个探测成功信息,否则反馈一个失败信息。
在前两次探测均成功的情况下进行第三次探测:首先仍然给DSP芯片发送一个数据‘aa’进行握手,握手成功后先给DSP芯片发送一个擦除命令,等待擦除成功后再给DSP芯片发送FLASH写操作命令,然后将数据段报文分包传输给DSP芯片,等待写命令成功完成后发送退出命令,上位机提示下载完成,否则任何一个步骤出错均反馈一个失败信息,中断文件下载程序过程。
上述第三次探测中将数据段报文分包传输给DSP芯片的过程为:根据用户程序COFF文件格式将其分成多个数据段,对每段进行分包处理,给每个包加上自定义的报头和报尾,以12帧数据为一个包进行发送,按数据段逐包发送,直到最后一个包发送结束。
步骤b6中写操作过程采用FLASH烧写算法:通过CAN总线接收上位机发送的用户程序分包数据,再根据用户程序段分配FLASH独立扇区,RAM缓存区中每接收到一个数据包就进行斩头去尾操作,立即将剩余的用户程序数据写入指定的FLASH内存区进行固化,采用边接收边烧写的方式,直到所有用户程序下载结束。
且FLASH中的存储空间的分配方式如下:FLASH 8个扇区中前四个扇区固化BootLoader程序,后四个扇区烧录用户应用程序。这样升级程序过程中规划分明互不干扰,当然根据两段程序的大小也可以适当调整FLASH内存空间,再不够的情况下,还可以扩展片外FLASH进行程序的固化。
本发明相比现有技术具有以下优点:本发明通过CAN总线对各个节点的DSP控制芯片进行在线程序升级,大大提高了对目标板进行在线升级和程序替换的效率和速度,避免了复杂的程序烧写过程以及嵌入式箱体封装所带来的不便。同时可根据用户定制的CAN口进行程序的下载,有效避免了数据干扰,漏包等现象出现;缩短了用户程序升级的时间,提高了升级效率;增加了上位机COFF文件解析功能,有效避免了对程序代码格式转换成BIN的繁琐过程,降低了用户程序烧写的复杂度,提高了工作效率;适当使用C和汇编混合编程以及代码搬移,合理地进行程序加载、内存分配和资源优化配置,进一步提高了对目标板进行在线升级和程序替换的效率。
附图说明
图1为本发明DSP芯片在线升级系统的结构框图;
图2为本发明中DSP芯片的自启动过程流程图;
图3为本发明DSP芯片在线升级系统的上位机操作界面;
图4为本发明DSP芯片从FLASH启动的顺序流程图;
图5为本发明DSP芯片加载升级程序的主要流程图;
图6为图2中COFF文件解析的具体流程图;
图7为图6中提取COFF文件段数据的具体流程图。
具体实施方式
下面结合附图对本发明进行详细说明。
如图1所示,本发明DSP芯片在线升级系统包括设置在上位机内的COFF文件解析模块、命令操作模块、应用程序下载模块、状态信息模块、CAN通讯模块,设置在下位机DSP芯片内的二次boot启动模块、用户程序升级模块。COFF文件解析模块对COFF文件进行解析后,将提取的段数据通过CAN通讯模块分包发送至DSP芯片。上位机的命令操作模块同过CAN通讯模块向下位机DSP芯片发送升级、探测、擦除、写、退出等命令。应用程序下载模块设置上位机三次探测过程,将上位机解析的数据段分包发送给DSP芯片。状态信息模块显示下位机的反馈信息。二次boot启动模块进行二次boot程序启动,选择是否需要进行程序升级功能。用户程序升级模块进行用户程序升级,即将上位机发送的程序数据段写入对应的FLASH储存区,替换旧的源程序完成升级。
如图2所示为TMS320F2833x系列的DSP芯片在本实施例中自启动过程流程图,即DSP从上电启动开始,完成默认从FLASH启动的全过程(图4所示),然后进入启动二次boot程序模式,根据上位机所发的指令状态选择是否进行程序升级,若需升级则直接进入用户程序升级模块,等待上位机启动用户程序下载模块,完成加载后上位机发送退出指令,退出bootloader程序跳转到用户程序入口地址,到此DSP升级完成一次生命周期,实现一次在线升级过程。
本发明DSP芯片在线升级方法具体过程如下:
S1:打开上位机软件,设置好必要配置,执行COFF文件解析模块;
打开如图3所示上位机软件,将CAN通讯端口类型、波特率、数据帧ID等进行配置,点击解析文件按钮执行文件解析工作,为升级做好准备工作,间接地提高了升级效率。
结合图6,COFF文件解析模块的执行过程如下:
a1.在CCS上根据.cmd内存分配要求编写用户升级程序,然后编译链接生成最终可执行的.out文件;
用户升级程序.cmd文件规划如下:
FLASHH : origin = 0x300000, length = 0x008000 // 程序段
FLASHG : origin = 0x308000, length = 0x008000 // 程序段
FLASHF : origin = 0x310000, length = 0x008000 // 数据段
FLASHE : origin = 0x318000, length = 0x008000 // 程序段
BEGIN : origin =0x33FFF6, length = 0x000002 // 注意在用FLASH_API烧写程序时,该段要指定FLASH存储区间,如本实施例中上述提到的地址0x308000
.cinit : > FLASHE PAGE = 0
.pinit : > FLASHE PAGE = 0
.text : > FLASHE PAGE = 0
codestart : > BEGIN PAGE = 0
.econst : > FLASHE PAGE = 0
.switch : > FLASHE PAGE = 0
IQmath : > FLASHG PAGE = 0
当然根据用户程序的大小可以适当分配FLASH内存空间,如可以通过如下程序合并各FLASH扇区以满足超大用户程序的需求:
FLASHABCDEFGH : origin = 0x300000, length = 0x040000 //最大可存储空间
b1.上位机直接加载用户程序.out文件进行解析,将解析完数据存放入缓存区和相应的变量中,生成一个扩展名为.sc文件进行保存;
如图7所示,首先分析.out文件(即COFF文件)的文件头以确定有多少个段,然后逐段分析段信息头,根据段属性标识以确定是否需要下载,段头中的绝对地址、段数据长度等信息作为升级文件的一部分,与需下载的段数据合并成最终的下载文件,最后以文件的形式保存所有解析得到的数据信息。
c1.使用TI工具dis2000.exe对.out文件进行反汇编,与上位机解析出的数据进行对比,确保上位机解析正确。
使用TI官方提供的工具可以对DSP生成的.out文件进行各种转化,如使用hex2000.exe将其转化为hex文件,然后可使用hex2bin2000.exe将其再转化成二进制bin文件,本实施例中使用dis2000.exe对.out文件反汇编,并且可以查看该COFF文件中用于下载的各个段的数据信息,主要是如下数据段:.cinit—.text—codestart—ramfuncs—.econst,具体方法如下:打开CMD命令行终端,进入dis2000.exe所在文件夹下,在命令行中输入“dis2000.exe xxx.out xxx.asm”即可,将得到的文件与源文件进行对比。
d1.提取COFF文件中对应的段数据。
S2:使用CAN通信方式连接DSP与上位机,启动CAN通讯模块并给DSP上电复位;
上位机部分使用VC6.0进行CAN通讯和用户程序升级界面开发,如图3所示。下位机部分使用TI生产的TMS320F2833x系列的DSP芯片F28335作为开发工具;二者之间通过北京爱泰CAN-bus通讯系列产品USBCAN-2I型CAN盒进行连接。点击图3所示连接CAN和启动CAN按钮即可完成CAN启动模块,然后再给DSP上电复位;
S3:DSP拨码开关均上拉,保持默认从FLASH启动,程序运行到主函数入口地址处;
如图4所示,DSP上电,默认拨码开关全部上拉四个GPIO都处于高电平,默认从FLASH启动,该过程为:Reset(0x3fffc0)[内容:initBoot()]—>bootloader(0x3ff34c)[内容:判断启动方式即SCAN GPIO状态(1111)]—>codestart(0x3f7ff6)—>_c_int00(看不到具体代码)—>main函数。
S4:开始启动第一个项目代码BootLoader即二次boot程序,延时等待约5s钟,若超时,直接跳转进入S8;
该第一个项目代码BootLoader是由用户自己开发的二次boot程序,区别于DSP厂商固化与芯片上的BootLoader,它是预先编写好的用于升级程序的内核程序模块,是首先利用仿真器,在DSP上烧写固化的一个核程序,用来获取CAN总线的控制权,完成FLASH_API程序升级操作。
这里的跳转程序使用汇编语言编写,跳转指令:asm("LCR 0x308000");0x308000即FLASHG扇区首地址,为用户程序codestart段入口地址,该地址需根据用户程序.cmd文件进行分配,此处综合使用了C与汇编混合编程的方式,大大提高了代码的可执行效率。
S5:上位机在5s内发送boot升级命令,若命令正确,则进入S6,若受到干扰或命令错误,则跳转到S2;
用户发送命令就代表需要升级程序,若命令有误就重新启动BootLoader,再次等待用户发送正确命令,确保用户能够进入升级操作更新程序。接收错误命令时通过延时等待一段时间,给用户足够时间修改并发送正确命令,提高升级效率。
S6:上位机应用程序下载模块启动,通过CAN通信与DSP建立连接,进行用户程序升级过程:将S1中解析后提取的COFF文件中的段数据,通过CAN通讯分包将其发送至下位机DSP芯片,更新FLASH中用户程序,完成加载用户程序升级;
具体的程序升级过程如图5所示:
a6.接收上位机发送的擦除命令,擦除用户程序所需固化的FLASH扇区(切勿擦除所有FLASH区),成功擦除后反馈信息告诉上位机擦除成功。
本实施例中自定义通讯协议,DSP通过CAN总线接收擦除命令L=0xAA45FFFF&H=0x8F69FFFF执行整个FLASH扇区擦除操作,成功擦除后反馈信息为L=0x5500FFFF & H=0x8F69FFFF,告诉上位机擦除成功。其中0xAA00 为Boot 命令头部, 0x45(E)为擦除命令“Erase”,0x55XX为应答回复命令,低8 位的XX 表示本次操作结果指示码,0x00表示擦除成功,0x8F69为CRC16校验码。
b6.接收上位机发送的写命令,然后使用CAN通信接收上位机发送的用户程序分包数据,再根据.cmd内存分配方式合理分配用户程序各段在FLASH中的存储空间,然后执行写操作将用户程序按数据段组包依次写入FLASH对应扇区,写成功后反馈信息告诉上位机FLASH写入成功。
COFF文件数据段下载过程包括如下三次探测:
第一次探测:首先给DSP发送一个数据‘A’进行握手,握手成功后则继续给DSP发送一个文件报文数据进行传输通讯测试,成功测试后反馈一个探测成功信息,否则反馈一个失败信息。
第二次探测与第一次探测基本相同:首先给DSP发送一个数据‘A’进行握手,握手成功后则继续给DSP发送另一个文件报文数据进行传输通讯测试,成功测试后反馈一个探测成功信息,否则反馈一个失败信息。
前两次探测均无问题的情况下进行第三次探测:首先仍然给DSP发送一个数据‘aa’进行握手,握手成功后先给DSP发送一个擦除命令,等待擦除成功后再给DSP发送FLASH写操作命令,然后将数据段报文分包传输给DSP,等待写命令成功完成后发送退出命令,上位机提示下载完成,否则任何一个步骤出错均反馈一个失败信息,中断文件下载程序过程。
用户程序CAN通讯数据传输方法为:根据用户程序COFF文件格式将其分成多个数据段,对每段进行分包处理,给每个包加上自定义的报头和报尾,以12帧数据为一个包进行发送,按数据段逐包发送,直到最后一个包发送结束。
本实施例中FLASH内存规划如下:FLASH 8个扇区中前四个扇区固化BootLoader程序,后四个扇区烧录用户应用程序,这样升级程序过程中规划分明互不干扰,当然根据两段程序的大小也可以适当调整FLASH内存空间,再不够的情况下,还可以扩展片外FLASH进行程序的固化。
用户程序内存分配主要有烧写程序决定,上述提到主要需下载烧写的程序段为.cinit—.text—codestart—ramfuncs—.econst这五段,这里需要注意.text段需要根据.cmd进行内存分配(固定),codestart段很重要是程序跳转的入口地址,可以任意指定,但必须明确具体地址,ramfuncs段也需要查看.cmd中程序加载情况进行正确分配,其它两段为数据段只要放在数据存储内存空间即可,分别对应指定COFF各段内存分配情况如下:
.cinit 0x314000~0x317FFF
.text 0x318000~0x31FFFF
codestart 0x308000~0x31FFFF
ramfuncs 0x300000~0x30FFFF
.econst 0x310000~0x313FFFF
BootLoader直接按.cmd内容进行规划如下:
FLASHD : origin = 0x320000, length = 0x008000 // 程序段
FLASHC : origin = 0x328000, length = 0x008000 // 程序段
FLASHB : origin = 0x330000, length = 0x008000 // 数据段
FLASHA : origin = 0x338000, length = 0x008000 // 程序段
BEGIN : origin =0x33FFF6, length = 0x000002
.cinit : > FLASHE PAGE = 0
.pinit : > FLASHE PAGE = 0
.text : > FLASHE PAGE = 0
codestart : > BEGIN PAGE = 0
.econst : > FLASHE PAGE = 0
.switch : > FLASHE PAGE = 0
IQmath : > FLASHG PAGE = 0
这里还必须进行一步重要的设置,就是将Flash281x_API库文件从Flash中复制至RAM里运行,该函数必须放在RAM中,在FLASH中无法操作FLASH_API。也可以将.cinit、.const、.econst、.text等代码段适当地由Flash复制至RAM中运行,能够有效提高代码的执行效率,部分代码搬移设置如下:
Flash28_API:
{
-lFlash28335_API_V210.lib(.econst)
-lFlash28335_API_V210.lib(.text)
} LOAD = FLASHD,
RUN = RAML0,
LOAD_START(_Flash28_API_LoadStart),
LOAD_END(_Flash28_API_LoadEnd),
RUN_START(_Flash28_API_RunStart),
PAGE = 0
FLASH用户程序写操作过程使用了FLASH烧写算法,即使用CAN口接收上位机发送的用户程序分包数据,再根据用户程序段分配FLASH独立扇区,RAM缓存区中每接收到一个数据包就进行斩头去尾操作,立即将剩余的用户程序数据写入指定的FLASH内存区进行固化,采用边接收边烧写的方式,直到所有用户程序下载结束。
c6.接收上位机发送的退出命令指示DSP编程操作完成,不用返回给上位机任何信息,直接退出BootLoader程序。
本实施例中接收的退出命令为L=0xAA51FFFF&H=0x61B8FFFF,0xAA00为Boot 命令头部,0x51(Q)为退出命令“Quit”,0x61B8为CRC16校验码。这里仍然使用汇编程序编写跳转指令,跳转到用户程序codestart入口地址:0x308000。
S7:DSP跳转到用户程序入口地址,进入S8;
S8:执行用户程序,完成boot升级功能。
通过该实施例能够体现本发明确实实际可行,并且能够达到以下较理想的技术效果:根据用户定制的CAN口进行程序的下载,有效避免了数据干扰,漏包等现象出现;缩短了用户程序升级的时间,提高了升级效率;增加了上位机COFF文件解析功能,有效避免了对程序代码格式转换成BIN的繁琐过程,降低了用户程序烧写的复杂度,提高了工作效率;适当使用C和汇编混合编程以及代码搬移,合理地进行程序加载、内存分配和资源优化配置,大大提高了对目标板进行在线升级和程序替换的效率。
最后需要说明的是:本发明的升级方法不局限于上述实施例中所限定的模块以及步骤执行顺序,具有说明性而非限定性,所属领域的技术人员应当理解:其目的在于让熟悉此项技术的人是能够了解本发明的内容并据以实施,本申请后依然可对申请的具体实施方式进行种种变更、修改或者等同替换,但这些变更、修改或者等同替换,均在申请待批的权利要求保护范围之内。