这是自己最近写的一个串口用BootLoader程序,包含PC程序以及MCU的程序。
之前在用ds30 loader,只是免费版的通讯不能加密,HEX不能加密。并且必须先烧写一次ds30 loader,然后再用ds30 loader烧写程序,实际用起来很是比较麻烦。所以就想自己开发一个解决这些问题。
PC端软件使用python3.2.3+pyqt4.9.4开发。hex文件目前采用3DES加密。
MCU用的是MCC3.3.1开发。不过这个因为要用在自己的产品中,所以代码中删除了加密代码,有需要可以自行添加。
性能上在串口19200速率下,使用加密时,120KB原始大小的HEX文件在24s左右更新完成。
PC端软件分为2部分:
1.生成HEX:这里是用来将编译器生成的原始HEX文件进行格式调整并且加密保存的。
2.写mcu:这部分是用来将前面一步生成的加密hex文件烧写进MCU的。
mcu部分:
直接将char BootLoader(void) 函数放在程序最开头部分即可。
int main(void)
{
BootLoader(void);
//其它代码
}
MCU部分使用方法:
1.修改gld文件,开辟bootloader使用区域,并且修改程序空间长度。目前使用的是0xA400之后的所有地址作为bootloader程序空间。
2.修改mcu源文件中.h文件中预定义以及.c文件中初始化。(必须定义对串口的RX脚,这样才能检测烧写信号)
3.编译后用烧写器将此文件烧进MCU即可。注意预配置中GWRP一定要为GWRP_OFF,否则无法串口升级。
PC部分
1.首先修改readHex.py和LoadHex.py两个文件中 desKey = DES3.new("1234567890123456", DES3.MODE_CBC) 的密码。
2.使用LoadHex.py生成需要烧写的HEX文件。
3.用bootMain.py开始烧写HEX文件,根据界面提示操作即可。
目前缺点:
1.配置位不能被跟新
2.bootloader不能被升级。实际就是从0xA400地址之后的空间都不会被更新。所以才需要修改gld文件加以限制。
gld文件.zip
(9.41 KB, 下载次数: 181)
2012-11-22 15:24 上传
点击文件名下载附件
gld
gld文件
MCU.zip
(3.24 KB, 下载次数: 200)
2012-11-22 15:24 上传
点击文件名下载附件
mcu代码
MCU部分代码
PC.zip
(13.77 KB, 下载次数: 165)
2012-11-22 15:24 上传
点击文件名下载附件
pc端代码
PC代码
这个代码主要是以实验性质为主,所以不能排除存在各种问题,如果要大规模使用时还需谨慎。本人水平有限,各位如果有什么意见和建议还望多多提出,谢谢。
这里需要区分是16,18系列还是24,33系列
16,18系列中断入口是固定地址,(高优先级0x08,低优先级0x18)。程序会分别在FLASH中,0x08,0x18地址处放置两条跳转语句,到实际的中断程序中。所以这个是没有办法完成中断重映射的。也就是bootloader中无法使用中断。
24,33系列差不多一样的结构,只是中断入口更多了,且每个入口都有一个备用入口(AIVT 备用中断向量表)。所以只需要定义好备用入口里面的跳转地址,就可以在bootloder中使用中断。
最后为啥这个bootloader要放在最后,是因为如果放在开头的话,必须要重新定义中断向量表跳转地址(因为程序偏后了)。懒得重定义中断向量表,而且bootloader中也没必要用中断,所以放在了最后。
谢谢楼主回复,我昨天也查了大量资料,最终都是不能在BOOTLOADER中使用中断,现在我用的是PIC18F25K80.
再请教下,如果BOOTLOADER放在FLASH前面,比如0X00-0X400,那主程序的中断向量是否要改为0x408和0x418?
我找了下,没找到相关的设置教程,昨天想把BOOTLOADER放到FLASH后半段,结果设置了偏移地址后,一直报错说
Error - section 'InterruptVectorHigh' can not fit the absolute section. Section 'InterruptVectorHigh' start=0x00000008, length=0x0000005c
现在还没解决,楼主有遇到过吗?
18就简单多了,因为中断入口是固定的。下面的isr_high就是你的高优先级中断程序
先说一下18系列中断进入的方法吧,以高优先级中断为例,当中断发生后,MCU会将PC指针强制指到0x08地址(此地址没有任何方法更改)。在0x08处只有一条汇编指令"GOTO isr_high"。执行后MCU跳转到isr_high函数所在地址,开始执行函数里的内容。
这里只说用XC8(PICC18)编译器的方法。
1.在设置了Code offset后,编译器会自动在(code offset + 0x08)处放置"GOTO isr_high",在(code offset + 0x18)处放置"GOTO_isr_low"。所以在APP中,对于中断程序也好,入口向量也好,不需要做任何更改。
2.当bootloader在FLASH最末尾时,如果又不需要上电后先执行bootloader,那其实你什么都不需要做,Code offset都不需要设置。
3.当bootloader在FLASH最开头时,因为中断入口是固定的,你必须手工加入两条跳转语句,在0x08处放置"GOTO code offset + 0x08",在0x18处放置"GOTO code offset + 0x18"。这样当中断触发时才能正常进入中断程序
我的实现方法是在0x08和0x18处建两个数组,数组内容翻译成机器码就是GOTO语句
- #define dCODE_OFFSET 0x0040 //偏移量
- //中断地址
- #define dISRH_ADD_HIGH (((dCODE_OFFSET+0x08)/2)>>8)
- #define dISRH_ADD_LOW (((dCODE_OFFSET+0x08)/2)&0xFF)
- #define dISRL_ADD_HIGH (((dCODE_OFFSET+0x18)/2)>>8)
- #define dISRL_ADD_LOW (((dCODE_OFFSET+0x18)/2)&0xFF)
- volatile const unsigned char vgotoisrh[4] __at(0x0008) = {dISRH_ADD_LOW, 0xef, dISRH_ADD_HIGH, 0xf0}; //GOTO code offset + 0x08
- volatile const unsigned char vgotoisrl[4] __at(0x0018) = {dISRL_ADD_LOW, 0xef, dISRL_ADD_HIGH, 0xf0}; //GOTO code offset + 0x18
复制代码你的那个报错是因为改了中断入口造成的,其实是多余的。
我不太清楚你具体的实现细节,如果是和我一样将Bootloader放在FLASH最末尾,且上电先进Bootloader的话,可以这样排查
1.程序的Code offset需要设置。我设置的是0x40,也就是把FLASH最开头的64字节空出来。
hex.jpg (69.79 KB, 下载次数: 0)
下载附件
2018-5-9 11:42 上传
4.直接拿烧录器读取FLASH,看下载的内容对不对。
谢谢楼主回复,可能 我用的编译器版本问题,其实我就想设置个基地址而已,奈何这编译器太差了,优化能力更差,折腾了好久,问题已经基本解决,我再测试下,到时开个贴共享出来。
之前看到有坛友千元酬金求18F25K80的BOOTLOADER,想必这东西比较冷门,应该有些许共享价值。
再次谢谢楼主的分享。
一周热门 更多>