BootLoader设计

基本概念

BootLoader是启动程序,主要作用就是做某些初始化动作和升级应用程序。根据升级方案的不同,可以分为带临时存储区域的和不带临时存储区域的。

带临时存储区域的升级流程里面,编程芯片将接收的到的升级文件以数据的形式放进临时区域,升级文件校验通过后,再将升级文件复制到应用程序区域。

不带临时存储区域的升级流程里面,编程芯片将接收的升级文件直接放到应用程序区域,升级文件校验。

两种方案的优缺点对比

带临时存储区域方案优点

1、升级失败的时候,应用程序功能不受影响。

2、升级流程绝大部分可以在应用程序中完成,BootLoader相对较小。

带临时存储区域方案缺点

需要额外的存储空间,耗时较长。

不带临时存储区域方案优点

节省存储空间,升级相对较快。

不带临时存储区域方案缺点

1、升级失败的时候,只能停留在BootLoader中,没有任何应用程序功能。

2、升级流程绝大部分在BootLoader当中完成,需要增加许多逻辑判断,BootLoader相对较大。

设计要点

一般有以下几个设计要点,我们这个项目采用不带临时存储区域方案,适用于存储区域小,要求实时性高的情况。

1、代码跳转:从应用程序跳转到BootLoader,从BootLoader跳转到应用程序。

2、保持上位机在线:该项目使用芯片为MCU,通过SOC芯片将获取到的数据传输下来。

3、升级失败和中途断电处理。

代码跳转

本质上就是在程序A中,将程序B存放的复位向量地址当做函数指针,通过函数指针运行程序B。

这里有个要点,跳转的时候目标地址要+4,这是芯片当中要求的。

举个例子

#define OBJ_ADDRESS	0x00000000//目标跳转到地址
 
uint32_t *Entry_ADDR = (uint32_t *)(OBJ_ADDRESS + 4);//目标地址要+4
 
typedef void(*JumpToPtr)(void);//类型定义
 
JumpToPtr pJumpToAddr;//定义个对象
 
pJumpToAddr = (void *)(*Entry_ADDR);//装载进函数
 
pJumpToAddr();

从应用程序跳转到BootLoader前一般需要关中断、清中断使能、清中断优先级、外围设备逆初始化、切换频率为正常工作频率。

保持上位机在线

SOC的电源管理在MCU,通过GPIO控制。这样我们进入BootLoader后,不初始化电源管理相关的GPIO。

升级失败和中途断电处理

这种情况本质上就是:该如何识别出升级未完成,避免跳转到应用程序当中?

我们可以先分析进入BootLoader里面的情况。

进入BootLoader有4种情况

1、从应用程序升级跳转到Boot:停留BootLoader等待升级

2、升级过程失败或升级过程超时:停留BootLoader等待升级

3、正常启动(应用程序正常):跳转应用程序

4、出厂启动(无应用程序):停留BootLoader等待升级

我们一般的方法就是,根据不同的情况,在Flash的特定位置写入特定信息,在需要的时刻读出判断,这个位置我们一般称为标志位。

升级标志位

1、升级状态标志位

2、应用程序校验通过标志位(一般应用程序区域的尾部)

操作标志位的时机

1、在应用程序中接收到升级命令,将升级状态标志位写为“升级开始/未完成”。

2、升级失败或升级过程超时,将升级状态标志位写为“升级失败””。

3、升级过程中擦除Flash,将应用程序校验通过标志位写为“不通过”。

4、升级成功,将升级状态标志位写为“升级完成”,应用程序校验通过标志位写为“通过”。

开发过程遇到问题

MCU异常复位

我们当时有两个项目同时进行,一个项目有复位问题,另一个项目没有复位问题,于是将两个项目的代码进行对比。经过排查,他们的区别在于BootLoader的Base代码里面底层配置了看门狗和定时器,在定时器里面喂狗。

定时器的问题是把也就是这个地方勾选上了。

通过芯片手册查到,这是使能了个外部触发的功能。

接口源代码如下

#define FTM_EXTTRIG_INITTRIGEN_MASK              0x40u
#define FTM_EXTTRIG_INITTRIGEN_SHIFT             6u
#define FTM_EXTTRIG_INITTRIGEN_WIDTH             1u
#define FTM_EXTTRIG_INITTRIGEN(x)                (((uint32_t)(((uint32_t)(x))<<FTM_EXTTRIG_INITTRIGEN_SHIFT))&FTM_EXTTRIG_INITTRIGEN_MASK)

/*FTM external trigger */
/*!
 * @brief Enables or disables the generation of the trigger when the FTM counter is equal
 * to the CNTIN register.
 *
 * @param[in] ftmBase The FTM base address pointer
 * @param[in] enable State of initialization trigger
 *                   - true : To enable
 *                   - false: To disable
 */
static inline void FTM_DRV_SetInitTriggerCmd(FTM_Type * const ftmBase,
                                             bool enable)
{
    ftmBase->EXTTRIG = (ftmBase->EXTTRIG & ~FTM_EXTTRIG_INITTRIGEN_MASK) | FTM_EXTTRIG_INITTRIGEN(enable);
}

其实就是这一位,使能的话,当定时器的数值等于CNTIN的数值就出发初始化定时器。

我们找到这个CNTIN寄存器,其实就是定时器的初始值,一到初始值就复位定时器,这样就经常复位定时器,拖长了喂狗的时间,偶发来不及喂狗。

操作升级标志位失败

本质上就是对Flash区域的读写。

发现在应用程序的时候操作失败,BootLoader里面操作成功。

在应用程序和BootLoader中对Flash都有初始化操作,在应用程序中对Flash的初始化失败了,尝试不初始化系统频率就成功了。

那我们在操作Flash的时候切换到正常频率,操作完再切换到高速频率就可以了。

在电源管理里面,HSRUN模式是高速频率,这时候操作Flash是失败的,要切换为RUN模式才能正常。

​​​​​​​

引导加载程序(bootloader)是计算机系统中的一个关键组件,它负责在计算机启动时加载操作系统。下面是关于bootloader设计的一些介绍: 1. 引导过程:引导加载程序位于计算机的固定存储器(如硬盘、固态硬盘或闪存)的特定位置,当计算机启动时,BIOS或UEFI会将控制权转移到引导加载程序的起始地址。引导加载程序首先进行硬件初始化和自检,然后加载操作系统内核到内存中,并将控制权转交给操作系统。 2. 引导加载程序的位置:引导加载程序通常位于硬盘的主引导记录(MBR)或EFI系统分区(ESP)中。MBR是硬盘的第一个扇区,它包含了引导加载程序的代码和分区表信息。而ESP是UEFI固件规范中定义的一个特殊分区,用于存储引导加载程序和操作系统相关文件。 3. 引导加载程序的功能:引导加载程序的主要功能是加载操作系统内核到内存中,并将控制权转交给内核。为了实现这一功能,引导加载程序需要完成以下任务: - 初始化硬件设备,如显示器、键盘等。 - 读取操作系统内核文件,并将其加载到内存中的指定位置。 - 设置内存保护机制,以防止操作系统内核被非法修改。 - 设置操作系统内核的启动参数,如命令行参数、硬件配置等。 - 转交控制权给操作系统内核,使其开始执行。 4. 引导加载程序的设计考虑: - 可靠性:引导加载程序需要具备足够的容错能力,能够处理硬件故障、文件系统错误等异常情况。 - 灵活性:引导加载程序应该支持多种操作系统,并能够根据需要加载不同的内核文件。 - 安全性:引导加载程序需要保证加载的内核文件是可信的,并能够验证其完整性和数字签名。 - 可扩展性:引导加载程序应该支持插件机制,以便于添加额外的功能或支持新的硬件设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃鱼的羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值