本人最近接手了一个51单片机的项目,要使用一个NB模块实现OTA远程更新功能,该51单片机的ROM容量为64KB,RAM为2KB,以前做过32单片机的OTA功能,以为很简单的修改KEILC51的魔术棒界面就能成功的,没想到实现起来蛮复杂的。
一、方案介绍
本人目前用的方案是将两个程序放在一起,框图如图1所示。
图1
实现OTA的思路为将两个程序放入同一个单片机中,用户程序中断向量表位置为0,用户程序的Main函数位置为0x100,OTA函数的中断向量表位置为0xF000,Main函数位置为0xF100,由于51单片机没有中断向量表偏移的功能,所以本文通过修改跳转地址来实现中断向量表偏移。
项目使用的51单片机中断向量表如图2所示。
图2
在汇编中,跳转指令为LJMP 0xHHLL,其生成的bin文件的二进制为02 HH LL,故当要跳转到OTA程序时,将涉及OTA的中断的地址进行修改,比如单片机的串口中断地址为0x23,bin文件中0x23-0x25为 02 B7 3B,将其修改为02 F0 23,即可实现OTA程序正常实现串口通讯。
二、具体操作
在编写OTA程序时,为了方便调试,需要将代码整体偏移,本文将OTA代码的位置放在0xF000到0xFFFE中,实现方式如图3所示。
图3
如果使用了中断,那也需要偏移中断向量表,由于51单片机没有偏移中断向量的寄存器,所以本文在STARTUP.A51中使用汇编手动偏移中断向量表。先在魔术棒中修改中断位置,操作方式如图4所示。
图4
由于已经偏移了中断向量位置,所以得在STARTUP.A51中编译跳转位置,使用CSEG AT 中断位置,找到中断地址,在使用LJMP 跳转地址,固定中断位置跳转后的地址如图5所示。在编译后的bin文件中,能验证操作的成功,如图6所示 。
图5
图6
将OTA程序调试完成后,将bin文件中代码空间中的二进制数据变为数组形式,存入到用户程序中,将该bin数据的地址固定,如图7所示。
图7
在进入OTA程序的代码中添加修改rom的函数,本文中的函数是我自己编写的,如图8所示,修改完bin文件后立马重启设备,就能实现用户程序到OTA程序的跳转。
图8
最后生成的bin文件包含了两个部分,如图9-10所示。
图9
图10