专栏首页知识分享06-STM32+ESP8266+AIR202远程升级方案-移植STM32+ESP8266实现利用http或https远程更新STM32程序到自己的项目(定时访问升级,备份升级)

06-STM32+ESP8266+AIR202远程升级方案-移植STM32+ESP8266实现利用http或https远程更新STM32程序到自己的项目(定时访问升级,备份升级)

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

移植BootLoader

1.凡是和ESP8266类似,通过串口配置通信的模块都可参照此节移植.

如果做项目,请大家必须使用STM32F103CBT6 及其以上的Flash>=128KB的单片机.

2.用户移植的时候首先保证自己的程序已经可以控制模块实现TCP通信(模块作为客户端)

3.我准备了一份空模板

该模板只有一个定时器,延时,串口

因为每个人写的程序都不一样,我假设我的模板也实现了控制模块实现TCP通信.

然后现在我就想移植我写的程序到一个新的工程里面作为BootLoader引导程序.

4.我复制出来一份空模板作为BootLoader

5.把BootLoader移植文件里面的BootLoader和mem文件夹复制到自己的工程

6.把文件添加到工程,并包涵下.h路径

7.需要添加操作 flash的库

8.编译工程,打开第一个错误

9.添加上自己的延时1ms函数

10,接着看下面两个错误

下面两个地方是向模块发送get指令

11,我的8266模块配置上TCP连接Web服务器以后如果是透传模式下我直接往串口发送数据

数据就会被8266转发出去

如果不是透传模式下,https的时候模块就不支持透传,我需要先发送AT+CIPSEND=数据个数

然后等模块返回 < 以后我再发送数据

所以我的修改如下(假设我是用串口1和wifi模块通讯)

12,把 IAPTimerOut(); 函数放到1ms定时器中断函数里面

13, 在主程序里面写上以下程序

注:AutoConnectTCP()函数是控制模块连接web服务器的函数,客户需要根据自己的程序实现此功能

连接的IP地址为: IAPStructValue.IP(字符串形式)   连接的端口号为:IAPStructValue.Port

连接成功以后返回 1

上面的IP地址和端口号是根据固件程序地址解析出来的

还有一个参数 IAPStructValue.SSLEN ; 0:http  1:https

如果客户使用的也是8266,可以参考测试升级源码中的例子.

如果客户需要把字符串形式的IP地址转换为数组形式,可使用下面的转化函数

/**
*@brief        检查字符串地址是IP还是域名
*@param        str 要转换的数据
*@param        ip  转换后存储的位置
*@return     0:转换失败,可能是域名   1:转换成功
*@example  UTILS_StrToIP("192.168.0.1", &ip) ip[0]=192;ip[1]=168;ip[2]=0;ip[3]=1;
*/ 
uint8 UTILS_StrToIP(const char* str, void *ip)
{
        /* The count of the number of bytes processed. */
        int i;
        /* A pointer to the next digit to process. */
        const char * start;

        start = str;
        for (i = 0; i < 4; i++) {
            /* The digit being processed. */
            char c;
            /* The value of this byte. */
            int n = 0;
            while (1) {
                c = * start;
                start++;
                if (c >= '0' && c <= '9') {
                    n *= 10;
                    n += c - '0';
                }
                /* We insist on stopping at "." if we are still parsing
                   the first, second, or third numbers. If we have reached
                   the end of the numbers, we will allow any character. */
                else if ((i < 3 && c == '.') || i == 3) {
                    break;
                }
                else {
                    return 0;
                }
            }
            if (n >= 256) {
                return 0;
            }
            ((uint8_t*)ip)[i] = n;
        }
        return 1;

}

14,把 IAPPutDataToLoopList(char Res); IAPHttpHead(char Res);

函数放到和模块通信的串口中断里面

15,如果模块不是透传模式,还需要修改接收数据部分

一般不是透传模式,模块接收每一条数据的开头都会携带着其它自己添加的信息

假设ESP8266在非透传模式下接收到123个数据,返回给单片机的数据为:

\r\n+IPD,123:真实数据

用户可以参考下面的剔除程序,修改为自己的剔除程序.

客户修改做的就是把真实数据写入环形队列.

16,设置下默认的固件程序下载地址(根据自己的服务器修改)

17,建议在BootLoader程序里面打开看门狗

可直接把我提供的升级源码中的看门狗复制过来

18,屏蔽掉BootLoader程序里面使用的中断

用户需要把自己的中断函数放到此处关闭!

19,关于日志打印口(必须有,便于查看Flash分配情况和更新过程)

所有的日志都是使用的printf函数打印

printf打印不得和控制网络模块的串口冲突!

printf打印最好加上缓存,中断发送方式(建议环形队列+中断)

如果用户用 USART_SendData(其它串口,c); 等类似的阻塞型的函数实现printf

请屏蔽以下部分

20,设置工程生成bin文件,然后编译下工程.

21,根据bin文件大小在 stmflash.h中调整下flash分配

STM32_FLASH_SIZE  根据自己的单片机容量调整

如果使用的是128KB Flash的单片机:

FLASH_IAP_SIZE XX   根据BootLoader生成的bin文件大小设置(该值需要大于生成的bin文件大小)

FLASH_UPDATE_SIZE 1  //存储更新相关数据所有FLASH大小,不需要改动.

FLASH_USERDATA_SIZE XX  如果用户存储的数据量比较大,增加该值即可

如果使用的是256KB及其以上 Flash的单片机:

FLASH_IAP_SIZE XX   根据BootLoader生成的bin文件大小设置(该值需要大于生成的bin文件大小,设置为4的倍数)

FLASH_UPDATE_SIZE 4  //存储更新相关数据所有FLASH大小,设置为4

FLASH_USERDATA_SIZE XX  如果用户存储的数据量比较大,增加该值即可(设置为4的倍数)

22,当前BootLoader程序已经移植完成

为防止意外情况,我提供的远程升级源码中增加了崩溃处理程序.

客户根据自己的情况参考移植使用!

重新设置URL

配置模块连接路由器

APUConfig配网

移植用户程序

1.我复制了一份空模板假设作为了用户程序

2.把BootLoader移植文件里面的BootLoader和mem文件夹复制到自己的工程

3.把文件添加到工程,并包涵下.h路径

4.需要添加操作 flash的库

5.打开 IAP.h文件 设置 IAPProgramSelect 为 IAPUserProgram

6.屏蔽掉下面部分

7.去掉屏蔽

8.修改型号和info.txt文件的下载地址(根据自己的情况修改)

9.编译下工程,打开下面的错误

10.把自己的延时函数放到此处

11.调整用户程序stmflash.h文件里面的配置

和BootLoader程序里面的保持一致

和BootLoader程序里面的保持一致!

和BootLoader程序里面的保持一致!

12.把BootLoader程序编译下,下载到单片机,根据打印的信息调整用户程序配置

SCB->VTOR = FLASH_BASE | 0xXXXX;

13,在主函数里面添加以下函数

14,自行增加使用get指令访问info.txt文件命令

连接的服务器的IP地址 IAPStructValue.IP(字符串)   端口号 IAPStructValue.Port

文件路径 IAPStructValue.Path

以上信息是由 IAPInfoPathInit();函数解析而来

连接访问参考原用户程序:

15,解析获取的文件信息

info.txt文件内容:

{"version":"0.0.1","size":15990,"url":"http://mnif.cn/ota/hardware/STM32ESP8266BK/user_crc.bin","info":"1.解决了部分BUG 2.优化了部分程序"}

判断版本号,本地版本号存储在 FirmwareVersion

如果版本还不一致,把固件程序大小和固件程序下载地址调用相应的函数存储

void IAPSetUpdateUrl(char* ch)  //存储url

void IAPSetFileSize(u32 data)    //存储size

然后设置更新标志,重启即可

IAPSetUpdateFlage();

IAPResetMCU();

16,至此用户程序也移植完成!

移植完成以后,用户按照我先前提供的测试流程测试.

由于我本人是当局者,可能会忽略到一些细节,

如果客户遇到什么问题,请联系我,我将根据客户的反馈完善此节文章.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 1-SDK开发初探-8266

    先分享一个比较感动的事情 ? ? ? ? ? ? ? 其实做实物是因为好多人看了我的文章之后还是会遇到各种各样的问题,然后呢真是让亲们搞的自己好累..........

    杨奉武
  • 04-STM32+W5500+AIR202基本控制篇-功能2-Android和微信小程序使用MulticastBind绑定W5500,并通过MQTT实现485,422通信和继电器控制(微信小程序)

    这节的功能是使用微信小程序绑定W5500,然后和W5500实现MQTT远程通信控制

    杨奉武
  • 6-51单片机WIFI学习(测试TCP服务器--使用串口调试助手--不连接路由器)

    上一篇连接  http://www.cnblogs.com/yangfengwu/p/8757513.html 注意:更加详细的操作请参考, http://ww...

    杨奉武
  • Python模块

    模块:在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用impo...

    用户7886150
  • Python面向对象(4)

    DataScience
  • Python快速学习第八天

    本文内容全部出自《Python基础教程》第二版 10.1 模块 现在你已经知道如何创建和执行自己的程序(或脚本)了,也学会了怎么用import从外部模...

    汤高
  • Python字符串split()和join()方法应用一例

    Python字符串对象提供了大量的方法,其中split()用来以指定的字符串作为分隔符对字符串进行分隔并返回列表,join()方法使用指定的字符串作为连接符对序...

    Python小屋屋主
  • python学习笔记(九)、模块

    使用import 语句从外部导入模块信息,python提供了很大内置模块。当你导入模块时,你会发现其所在目录中,除源代码文件外,还新建了一个名为__pycac...

    py3study
  • 【JS】382- JavaScript 模块化方案总结

    本文包含两部分,第一部分通过简明的描述介绍什么是 CommonJS、AMD、CMD、UMD、ES Module 以及它们的常见用法,第二部分则根据实际问题指出在...

    pingan8787
  • Node.js 如何处理 ES6 模块

    一种是 ES6 模块,简称 ESM;另一种是 Node.js 专用的 CommonJS 模块,简称 CJS。这两种模块不兼容。

    ruanyf

扫码关注云+社区

领取腾讯云代金券