note - bug fix - usage of fence

bug fix - add fence to protect atomic operation

记录两个 bug,risc-v relaxed memory model 会导致 mcu 写寄存器延时,由此导致的问题;
原理可参考 note - risc-v memory model - usage of fence

bug 1. bootloader jump failed

1.1 背景介绍

1.1.1 bootloader 方案

实现 bootloader + application,在 bootloader 中实现串口烧录和识别目标固件并跳转;
常规 bootloader 设计分两种:

  1. bootloader + application running area + application ota backup area
    ota 即固件在线更新;
    该方案每次实现 ota 时将固件更新到 ota backup area,重启后由 bootloader 从 backup area 拷贝固件至 running area 再运行,该方案为芯片设计限制,固件必须在指定位置运行。
  2. bootloader + application area A + application area B
    该方案每次实现 ota 时将固件更新到非运行的另一块区域,即当前运行 A 则更新至 B,当前运行 B 则更新至 A,随后重启,通过 bootloader 识别高版本固件再指定跳转。
1.1.2 telink soc 多地址启动

由于 telink series soc 支持多地址启动,可采用上述方案 2,所以 bootloader 可直接跳转到目标地址,而无需将 ota 固件拷贝到指定运行地址。

soc 多地址启动通用原理:
soc支持 0/0x20000/0x40000/0x80000 地址启动,上电 soc 通过识别多地址位置对应的标志位(通常为固件中起始位置固定偏移处存有固定的启动标志位,如 telink 会在固件偏移 0x20 byte 的位置填充 “TLNK” 四个字符作为启动标志);
检查到对应启动标志位后,即默认当前偏移地址作为基地址,以 0x20000 为例,随即设置偏移地址寄存器(reg_multi_addr),即 soc 默认将 0x20000 视为 cpu 取址的 0 地址,举例:flash_addr = cpu_addr + reg_multi_addr; flash 取址会默认在 cpu 取址基础上加上对应的偏移地址;

1.2 问题现象

当固件 ota 完成后重启,bootloader检测到 0x20000 有新固件,跳转时出现异常,application 无法正常工作。

1.3 原因

首次上电有硬件检测有效固件位置,并设置偏移地址寄存器(reg_multi_addr),首次上电会检测到 0 地址的 bootloader 并运行,此时偏移地址寄存器(reg_multi_addr)默认为 0 地址;
当 bootloader jump 到固件位置时,由 bootloader 检测并设置偏移地址寄存器(reg_multi_addr)。

reg_multi_addr = addr;//line 1
jump;//line2

由于risc-v relaxed memory model 影响,line 1 设置但未实际写入寄存器,此时执行了 line 2;
下面分为两种 case:

  1. application firmware 位于 0x8000,硬件偏移地址为 0,软件偏移地址为8000(后续介绍),此时即便 line 1 未执行成功,reg_multi_addr 为上电检测到 bootloader 设置的初始值,还是为 0,所以不影响,当前 case 运行成功;
  2. application firmware 位于 0x28000,硬件偏移地址为 0,软件偏移地址为8000(由于烧录不同地址的固件需要保持一致,所以软件偏移地址固件,需要在基地址基础上偏移 0x8000),此时 line 1 未执行成功,reg_multi_addr 为上电检测到 bootloader 设置的初始值,还是为 0,但是软件 jump 到了 0x8000 的位置,导致取址出错;
    2.1 如果 reg_multi_addr = 0,软件会取 flash 0x8000+reg_multi_addr = 0x8000 位置;
    2.2 如果 reg_multi_addr = 0x20000,软件会取 flash 0x8000+reg_multi_addr = 0x28000 位置;
    导致偏移地址寄存器未生效,bootloader jump 取地址错误,所以软件异常。

1.4 解决办法

reg_multi_addr = addr;//line 1
fence;
jump;//line2

在 jump 之前加入 fence,确保 reg_multi_addr 设置成功,偏移地址寄存器生效,随后 jump 取址即正常。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值