1.术语
ISP : In-System Programming
在系统编程,是一种通过MCU(微控制器单元)上的内置引导程序(BootLoader)来实现对芯片内部存储器(如Flash)进行编程的技术。
华大目前对应的ISP
IAP:In-Application Programming
在应用编程,是用户通过自己的程序更新程序固件的技术 ,如OTA升级、串口升级。
DFU: Device Firmware Upgrade
是一种 通过usb 设备驱动更新固件的技术
2. OTA方案
512K、 8k一个扇区 共64个扇区 | ||||
BOOTLOADER_A | APP_A | OTA FIRMWARE | CONFIG | OTA SIGN |
16K | 232K | 248K | 8k | 8k |
OTA SIGN 内容
OTA SIGN | ||
起始位置 | 长度 | 内容 |
B0-B7 | 8 | 固定字符串ABUP |
B8-B11 | 4 | SIGN ABUP_OTA_SIGN_A 、 ABUP_OTA_SIGN_READY_B、 |
B11-B15 | 4 | 保留 |
boot:查看OTA SIGN标志 运行APP_A 或从APP_B
app:app运行起来,如果当前是B区,且运行OK,保存APP_B 否则 运行APP_A 进行回滚
2.1 流程图
3. OTA方案中遇到的问题
3.1 怎么区分固件是 带boot或不带boot
const uint8_t device_name[16] __attribute__((section(".ARM.__at_0x00000FF0"))) = "BOOT_DEVICE";
可以使用此方法加固定标志位,在第1个4K收到时即可知道是否是带boot
3.2 boot引导A区或B区启动不起来
修改jump_to_app函数,增加 SCB->VTOR = 0 | start_addr;
boot时VTOR 为0------>A区时VTOR为4000
boot时VTOR 为0------>B区时 VTOR为42000
void jump_to_app(uint32_t start_addr)
{
/* Check if valid stack address (RAM address) then jump to user application */
if(((*(__IO uint32_t*)start_addr + 4)&0x1FFF8000)==0x1FFF8000)
{
Abup_Delay(500);
__disable_irq();
/* Jump to user application */
JumpAddress = *(volatile uint32_t*) (start_addr + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(volatile uint32_t*) start_addr);
SCB->VTOR = 0 | start_addr;
Jump_To_Application();
/* do nothing */
while(1);
}
else
{ /* Otherwise, do nothing */
while(1)
{
TRACE("Jump fail ...\r\n");
Abup_Delay(1000);
}
}
}
3.3引导到B区特别慢问题,但A区特别快
APP关闭 ICG ,统一 在boot添加 0x400
3.4 SEGGER打印接收数据不完整问题
关于使用J-Link RTT 打印日志内容不全问题的解决方法_rtt打印延时-优快云博客
3.5 电脑模拟ota数据发送,但是经常接收不到问题(报ORE、FE帧错误)
经仿真测试发现:
经常会卡死在rt_assert_handler 断言 rt_err_t rt_thread_resume(rt_thread_t thread)中
怀疑是内存不够导致
3.7 按照malloc 4k 左右空间 作为保存ota数据,一次性写入rom,但是申请的指针ota_controll,会被清零
使用ota_controll= (struct OTA_CONTROLL_ST *)rt_malloc(sizeof(struct OTA_CONTROLL_ST))