Bootloader(MDK AC5) 进阶版(一)

为什么要讲bootloader

1.转为一名不算真正的嵌入式软件工程师,起初对bootloader理解起来非常的吃力。如同天书一般,经过积累,后来也慢慢的开始熟悉起来。什么叫bootloader,为什么boot引脚有这么多组合。这个我建议大家可以看看网上的相关教程。本节内容主要从工程的角度来看待相关问题,当然也有一些不足还请指正。

BOOT在跳转前为什么要为APP提供干净的运行环境?

我们知道,BootLoader也是一段人为编制的程序代码,那么需要使用到一定的外设,以及中断向量的设置,一般的处理都是在跳转到APP前一个一个清除相关外设以及中断设置。这有一个隐患,就是可能BootLoader未清除干净导致APP运行环境混乱,代码会出现意想不到的问题。举个例子,就相当于埋了个地雷,你没踩到只是一时幸运,踩到了那就说明你前期没做好排雷工作。

如何提供一个干净的运行环境??

借用一张图:

怎么去理解这张图呢?

第一,我们想要把环境清除干净,除了手动清除每个外设,中断设置外,还可以通过复位。有的人可能会问复位后,系统不是又跳转到bootloader里了吗,那意义是啥? 这个就需要一个标志,那如何去设置呢,可以用全局变量吗?

首先我们先看这段代码:

uint32_t g_JumpInit __attribute__((at(0x2000A000), zero_init));

看不懂没关系,来看看AI是如何解释这段话的 

那为啥不同全局变量:

来看看区别

可以简单理解成全局变量初始化后值不变,而g_JumpInit可以被初始化为0的全局变量。

下面了解其作用后,我们再来看看如何保证g_JumpInit如何不被初始化。

设置MDK的STC文件

注意(初次设置点击Edit无效,需要先去掉勾选)

设置初始化为0的全局变量

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x0000A000  {  ; RW data
   .ANY (+RW +ZI)
  }
  
  RW_IRAM2 0x2000A000 UNINIT 0x00006000  {
   .ANY (NO_INIT)
  }
  //注意地址必须在范围内,例如我用的407VE芯片,RAM是64K,整个RAM是0x20000000-0x20010000,两个加起来不能超过这个位置
  
}

设置好后就可以使用g_JumpInit,需要注意一点,我们在跳转前硬件初始化后,再次进入boot程序不能将跳转程序放在硬件初始化后执行,否则毫无意义。一定要在进入int main 就马上跳转,不要进入init后再跳转,这是个小细节。

### MDK Bootloader 使用指南 当涉及到嵌入式系统的开发,尤其是像STM32这样的微控制器平台时,Bootloader扮演着至关重要的角色。对于MDK环境下的Bootloader操作,理解其工作原理以及掌握有效的配置方法至关重要。 #### 1. 理解Bootloader的工作流程 Bootloader作为启动加载器,在系统上电或复位后最先执行的段代码,负责初始化硬件并准备运行应用程序。在某些情况下,它还提供种安全的方式来进行固件更新[^2]。 #### 2. 配置Bootloader 为了使Bootloader能够正常运作,通常需要通过特定工具如STM32CubeMX来设置必要的参数: - **选择合适的MCU型号**:确保选择了与目标设备相匹配的处理器系列。 - **定义入口地址**:指定Bootloader开始执行的位置,这通常是闪存中的固定偏移量。 - **启用相应外设接口**:如果计划通过UART或其他通信端口接收新本的应用程序,则需激活这些功能。 ```c // 示例:简单的bootloader跳转到应用部分实现方式 void JumpToApplication(uint32_t applicationAddress){ typedef void (*pFunction)(void); // 检查APP向量表首字是否有效(非0) if (((*(__IO uint32_t*)applicationAddress) & 0x2FFE0000 ) == 0x20000000){ SCB->VTOR = applicationAddress; // 设置向量表基址寄存器指向新的位置 pFunction app_start = (pFunction)(*(__IO uint32_t*)(applicationAddress + 4)); __set_MSP(*(__IO uint32_t*)applicationAddress); // 初始化堆栈指针 app_start(); // 跳转至用户程序起点 } } ``` #### 3. 常见问题及其解决方案 针对“could not stop cortex-m device”的错误提示,可能是因为调试过程中遇到了Cortex-M内核无法暂停的情况。这类问题可以通过调整IDE内的调试选项或者优化Bootloader逻辑得到缓解。具体措施包括但不限于: - 修改链接脚本以防止覆盖掉用于调试的关键区域; - 在进入主循环加入适当延时以便稳定CPU状态; - 如果使用JTAG/SWD模式连接,请确认物理连线完好无损且适配器驱动已正确安装[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值