完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、烧写程序三种方式
嵌入式系统的主要升级方式有ICP、IAP、ISP。
首先,我的思路是将STM32的FLASH区域化分为四大区域,例如我使用的是STM32F103VET6,该芯片的FLASH区域有512K。第一块区域大小为50K,用来存放BOOTLOADER程序。第二块与第三块区域可以每个分200K大小,用来存放用户应用程序一(APP1)与用户应用程序二(APP2)。第四部分就用来存放各种标志位,比如当前运程的程序标志、应用程序版本标志等等。如果当前是运行在APP1下,那么接收到的升级程序就要写在APP2的区域内。我采用的是MQTT协议来实现远程升级,设备端使用Wi-Fi连接至互联网,通过MQTT协议连接至云端服务器。这里用的MQTT服务器为EMQX,并使用python作为另一个客户端(paho-mqtt)连接至服务器,这样就实现了python写的客户端与设备终端之间的通讯。 终端设备程序流程图(示意): (1) BOOTLOADER BOOTLOADER程序程序负责根据升级FLAG去跳转至对应的APP程序,没有其他工作。在编译时要制定FLASH空间,分配50K的大小。跳转的程序就不列出来了,有很多可以参考的例程。 (2)用户应用程序一(APP1) 使用ESP8266模块连接Wi-Fi,并通过MQTT协议连接至云端服务器。由于我的应用程序中使用了ucOSIII与emwin所以,bin文件会比较大。此时使用MQTT协议一次发送数据包过大可能会引起数据丢失等错误。所以为了避免这些错误。经测试,一次发送4K左右的数据包时可以保证数据的完整度。所以当bin文件大小为200K左右时,需要将其分成50个数据包来发送数据。如果要实现多台设备终端升级时,可以考虑先订阅一个升级包,收到该主题的消息后就取消订阅。这样两个设备之间不会相互影响。 APP1的地址要避开其他。 一定要在main函数中加入这条。放在最前面,设置中断向量表的偏移。 SCB->VTOR = FLASH_BASE | 0x0800C800; (2)用户应用程序二(APP2) 同APP1 同样要在main函数中首先设置中断向量偏移。 SCB->VTOR = FLASH_BASE | 0x803E800; 3、Bootloader程序 1.首先先给主函数的例子 2.iap_load_app()函数 3.这样就完成每次读取(FLASH_FLAG_ADDR 0X08070800)这个地址的存放的数据,然后根据读出的标志是0还是1来跳转至相应的APP区域执行程序。 4.关于升级文件的接收 首先我们的单片机要连接到EMQ X服务器,然后订阅相关的升级Topic。当单片机发送升级请求时,使用python编写的MQTT客户端接收到请求,根据所要升级的文件大小,将其分成若干个小包(我这里测试过每包分为4K的大小单片机可以正常接收数据)。每个小包为一个Topic,然后将数据发送至单片机。单片机每接收一个topic,经过检查后将其写入FLASH。接收完所有的升级包后,将FLASH_FLAG_ADDR中的标志位置0或1,通过软复位来进入bootloader程序。然后bootloader程序根据标志位跳转相应的APP区。 |
|
|
|
只有小组成员才能发言,加入小组>>
3263 浏览 9 评论
2944 浏览 16 评论
3443 浏览 1 评论
8955 浏览 16 评论
4036 浏览 18 评论
1079浏览 3评论
559浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
552浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2287浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1848浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 17:54 , Processed in 0.933405 second(s), Total 49, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号