zoukankan      html  css  js  c++  java
  • STM32+ESP8266+AIR202/302远程升级方案-程序优化1-bin文件识别,bin文件有效性检测

    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_B/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    前言

    远程升级方案已经有好多家公司和开发者在使用,使用过程中反馈了一些问题.

    这一节解决一个关于bin文件识别的问题.

    问题由来

    1.假设一家公司正在做两个项目(A项目和B项目),都是使用的同一款单片机,而且内部中断偏移设置的也一样.

    然后工程师们为了赶项目,天天熬夜加班,然后A项目更新了一版程序,准备上传到服务器.

    结果工程师不小心把B项目的文件替换了原先A项目的云端的程序文件!

    就是说,上传错了!!!!

    因为都是使用的同一款单片机,而且内部中断偏移设置的也一样,

    所以A项目的单片机下载了程序文件以后也是可以运行的!!!

    这不是坏了,原先A项目的单片机运行了B项目的程序!!!!

    2.又或者本身A项目的bin文件下载地址是 XXXXX/aaaa/a.bin

    结果有个工程师把下载地址改为了 XXXXX/bbbb/b.bin

    这不是又坏了,原先A项目的单片机运行了B项目的程序!!!!

    问题的根本

    单片机怎么判断,自己下载的bin文件就是自己的文件???

    解决思路方案

    每个项目/产品都会在程序里面设置一个型号.

    BootLoader程序和用户程序里面的型号保持一致.

    每次编译用户程序的时候把型号编译到bin文件里面.

    BootLoader里面执行升级的时候去查看bin文件里面有没有和自己一样的型号(字符串).

    开始优化(用户程序)

    1.注意

    请用户参考此文章自行对代码进行修改!原先的教程源码不再一一更改.

    2.打开用户程序的IAP.c文件,把原先的记录型号的数组做如下更改

    char DeviceModel[50] __attribute__((at(FLASH_BASE | 0x4800+1024*1))) = "STM32ESP8266BK";

    注意FLASH_BASE | 0x4800 这个是中断偏移,要和主函数保持一致

    3.为什么是 +1024*1

    把型号存储在偏移1024字节flash的位置
    第一是留出前面的单片机自己需要用的空间
    第二是数据校验间隔为128/256/512/1024,需要避免生成校验数据的时候把型号给截断.
    而且我希望型号存储的开始位置是校验数据的开始位置,方便我提取判断,所以取1024的倍数.

    用户程序只做这一个修改就可以了.

    开始优化(BootLoader程序)

    1.在BootLoader程序中的IAP.h的宏定义状态里面增加一个程序无效的标志

    #define UpdateStatus_ProgramInvalid    0xE8  

    2.在BootLoader程序中的IAPStruct结构体里面增加一个变量

    char ProgramEfficient;

    3.在BootLoader的IAP.c文件里面的获取程序文件函数里面清零这个变量

    IAPStructValue.ProgramEfficient = 0;

    4.在BootLoader的IAP.c文件增加记录型号的数组(型号和用户程序里面的保持一致)

    char DeviceModel[50] = "STM32ESP8266BK";

    5.在IAPWriteData函数里面的提取数据以后增加判断型号的程序

    注意:注意:注意:

    如果自己程序的printf是阻塞式打印,请屏蔽掉printf !!!!!!!

    if(IAPStructValue.ProgramEfficient == 0)
                {
                    if(memcmp(IAPStructValue.CheckDataBuff,DeviceModel,sizeof(DeviceModel)) == 0)//ÅжÏÐͺÅ
                    {
                        IAPStructValue.ProgramEfficient = 1;//Ò»ÖÂ
                        printf("
    ÐͺÅÒ»ÖÂ:%s
    ",DeviceModel);
                    }
                }

    6.在接收数据完成里面,判断如果程序无效,则重启执行回滚程序

    if(IAPStructValue.ProgramEfficient == 0)//ÎļþÎÞЧ
                {
                    IAPSetUpdateStatus(UpdateStatus_ProgramInvalid);//дÈëÎļþÎÞЧ±ê¼Ç
                    /*Èç¹û²»Ð´ÏÂÃæµÄÖØÆô,Ôò³ÌÐò»á³¢ÊÔÏÂÔØ,ĬÈÏ3´Î*/
                    printf("
    ³ÌÐòÎÞЧ,ÕýÔÚÖØÆôÖ´Ðлعö!
    ");
                    delay_ms(500);
                    IAPResetMCU();//ÖØÆô
                }

    测试

    1.分别编译下载现在的BootLoader程序 和 用户程序  到单片机

    2.把用户程序生成的bin文件用OTA Tools软件生成带有校验数据的文件

    3.把文件放到服务器

    4.观察日志

    5.把用户程序里面的型号改一下(测试是否可以做到有效性检测)

    6.编译,用OTA Tools软件生成bin文件,上传到服务器

    7.查看日志

    结语

    为便于后期移植使用,BootLoader 里面的IAP文件

    和用户程序里面的IAP文件最好保持一致!

     

  • 相关阅读:
    Your branch and 'origin/master' have diverged, and have # and # different commits each, respectively
    testng dataprovider 的几种用法以及Java中的二维数组
    python 类属性 实例属性 类方法 实例方法 静态方法(转载)
    Webdriver中PageFactory的正确用法
    Selenium webdriver在最开始打开的时候浏览器的地址栏会出现data的解决方法
    Selenium webdriver如何处理confirm对话框的问题
    SoapUI 引用第三方jar包和引用Groovy脚本
    git rebase -i 合并commit
    Git 撤销commit的注意事项
    单进程执行
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/13975579.html
Copyright © 2011-2022 走看看