从IAP升级到涂鸦OTA升级介绍(上)

仅作为个人学习笔记使用

序言

虽然说是重复造轮子,但是我觉得学习阶段还是很有必要的 主要目的验证数据接收(环形缓冲队列+空闲中断)以及重新复习IAP。本篇内容分为上下两部分 第一部分介绍传统IAP升级的方案到实现,第二部分介绍Tuya平台OTA升级使用及SDK代码部分介绍

上篇

一、什么是IAP升级

IAP--In Application Programming. 即在线应用编程,也就是说用户可以使用自己的程序对单片机的user flash区域进行烧写。可以很方便的对已经发布的产品进行功能升级或者程序上的修复,只要保留预先的通信接口即可(USART, 网口等),避免了要进行拆机使用下载器进行烧录。

而进行IAP升级最核心的两点是实现:

1.BootLoader程序的编写 存储在FLASH中,主要负责引导APP程序的升级

2.APP程序的编写 实现产品功能升级的程序或者对程序的修复

二、解析STM32如何启动方式

2.1 STM32 FLASH空间划分

以STM32F103RC为例,可知 其FLASH大小每页2K字节,内部FLASH的首地址从0x08000000开始 程序在此地址开始写入。由于后续要涉及到将bin文件写入FLASH,这里简单说下对FLASH写操作过程,首先要清楚一下几点:

字=32位=4个字节;半字=16位=2个字节

每次写入必须是两个字节

写入之前是必须先擦除的

FLASH地址为空的时候0xffff

擦除: 页擦除

FLASH写入过程

1.解锁

2.擦除扇区

3.写数据到指定位置

4.上锁

IAP时FLASH地址空间具体划分如下

2.2 STM32的启动过程

无论是Keil MDK还是IAR EWARM开发环境 ST公司都已经帮你写好了cortex内核的启动程序,你只需要进行引用就好 大大降低了开发难度。传统的ARM架构总是从地址为0处开始执行第一条指令,而Cortex-M3内核却不相同 有三种启动方式

1.通过boot引脚设置可以将中断向量表定位于SRAM区 即起始位置0x2000000 复位后PC指针0x2000000

2.通过boot引脚设置可以将中断向量表定位于FLASH区 即起始位置0x8000000 复位后PC指针0x800000(最常用的方式)

3.本文暂时不对这种情况论述

1)没有IAP 只有APP程序的正常流程

STM32的FLASH地址起始于0x08000000, 程序从此地址开始写入

根据上图分析启动和执行流程

1.STM32在复位后,从0x08000004地址处取得复位中断向量起始地址,并跳转到复位中断程序入口

2.在执行完复位中断程序后,会跳转到main函数

3.由于main函数一般数一个while(1)的循环体,在程序执行过程中发生中断时,PC指针会被强制指回中断向量表

4.根据中断源进入相应中断服务程序

5.执行完中断服务程序后 返回main函数

2) 加入IAP后流程

同理对流程进行分析

1.STM32复位后,从0x08000004地址处取得复位中断向量地址,随后跳转到复位中断程序入口,并执行完复位中断程序 最后跳转到IAP的main函数入口(这里将原先的步骤1和2进行合并)

2.在执行完IAP后(固件升级后),会跳转到APP的复位中断向量起始位置 即复位向量表处

3.取复位中断向量地址后,跳转到新的复位中断程序入口 并执行新的复位中断程序 最后进入APP的main函数

4.APP的main函数是一个while(1)循环体,在程序执行过程中发生中断后 (此时有两个中断向量表)先将PC指向0x08000004,再根据相应中断源进入中断函数

5.执行完中断函数后再回到APP的main函数

三、IAP升级方案介绍

主要实现两个事情,1)BootLoader程序 2)APP程序

升级APP无非是将旧程序换成新程序,就是一包一包的接收然后再一包一包的写入FLASH中,而在实际开发中为了确保数据接收的完整性 一般会设定传输协议 帧头 数据 校验位等,根据协议进行一包一包的校验。这里主要是为了验证IAP升级的demo 测试数据接收的写法 所以就不设置相关协议类似于直接将接收的bin文件存到FLASH的指定地点中

IAP升级流程

1.接收APP (bin文件)

这里采用环形队列+空闲中断的的方式

实际上数组就是一个大的队列,但是随着接收数据的增加 增加到数组最大容量后就会出现假溢出现象,数组就无法使用了,所以环形队列出现了。

一个字节一个字节的数据接收后进入中断,在环形队列(大小256)中先判断写指针和读指针是否重合,是则返回0xff, 否则写入USART_RECV_BUF,每次写入一个数据,后写指针(入队指针)加进行加一

next_pos = (p_queue->tail_pos + 1) % USART_BUFF_LEN; 主要是防止写指针越界

读出环形队列数据并直接写入FLASH指定位置中

这里说明几点:

1.FLASH在擦除、写入时候会花费较长时间 所以为了避免队列读出的数据直接写入FLASH过程中接收的其他接收的数据会丢失 在初始化时先将要写入的页及可能用到的页全部擦除,方便直接写入

2.在测试过程中,串口助手发送大约几十个字节 FLASH写入正常,但是将bin文件发送出去时候 会出现FLASH数据写入一半后会出现程序跑飞 可能还是串口发送的速度太快而在FLASH写入中很慢 所以后面将串口波特率改为9600 经过测试是完全没有问题的

3.STM32属于小端模式 对写入FLASH的数据要进行处理

4.FLASH写入/读出半字也就是一次写入2个字节,写完/读出一次地址会加2

同样这里是为了防止越界,并且每次读取一个字节数据后 长度都进行减减操作

2)跳转APP

判断程序是否已经完成拷贝到FLASH中 后开始执行FLASH中代码

程序运行时是在SRAM中,SRAM的栈顶地址0x20000000 也就是判断程序是否已经拷贝完成

四、怎么生成bin文件

首先要保证FLASH地址和BootLoadert中设定的相同

其次在这里输入 fromelf.exe --bin -o "$L@L.bin" "#L"

编译后就会生成如下所示 表示bin文件已经生成好了

最后在串口调试助手中点击发送文件即可

五、测试结果

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值