昆山做网站的,淘客的手机网站怎么做,wordpress老萨,wordpress 4.5 浏览器ie8.01 什么是bootloader#xff1f; Bootloader#xff0c;也被称为引导加载程序#xff0c;是操作系统启动过程中的一个重要组成部分。它是存储在非易失性存储器中的一段小程序#xff0c;负责在操作系统内核运行之前加载并启动一些必要的系统组件。 当计算机开机后#xff0…1 什么是bootloader Bootloader也被称为引导加载程序是操作系统启动过程中的一个重要组成部分。它是存储在非易失性存储器中的一段小程序负责在操作系统内核运行之前加载并启动一些必要的系统组件。 当计算机开机后BIOS基本输入/输出系统会首先运行检查并初始化系统硬件然后从设定的启动设备如硬盘、U盘等中找到Bootloader并把控制权交给它。Bootloader随后开始执行它会加载操作系统内核到内存并传递一些必要的系统参数。 
2 为什么需要Bootloader Bootloader的任务很重要因为它构成了硬件和操作系统之间的桥梁。如果没有Bootloader操作系统就无法启动。Bootloader还通常包括一个用户接口允许用户在多个操作系统中选择一个进行启动或者修改操作系统的启动参数。 
3 Bootloader实例 Bootloader的具体实现和功能可能根据操作系统和硬件的不同而有所差异。例如Linux系统常见的Bootloader有GRUB和LILO而Windows系统通常使用的是NTLDR或BootMGR。 说实话从单片机角度来说上述例子并不典型。这里举个最为典型的例子ArduinoIDE为何能给Arduino开发板下载程序就是因为开发板上搭载了Bootloader。当串口启动后Arduino即进入复位进入Bootloader程序进行监听串口接受串口下发的应用程序将应用程序写入arduino芯片中。这样就可以不通过ISPJTAG等方式而是通过串口实现了芯片上程序的更新。 具体原理笔者在之前的文章写过可跳转 
Arduino是如何实现打开串口时程序复位的-CSDN博客 
4 如何实现在STM32的bootloader程序 根据上面举的arduino的例子我们来实现一个STM32版本的通过串口更新程序的bootloader吧。 其运行原理大致可以归纳为以下几个步骤 上电复位首次给STM32供电或者按下复位键后STM32会开始从预设的启动地址一般是内部Flash的起始地址或者其他特定内存位置开始运行程序。  启动阶段在供电后的最初阶段STM32的Bootloader会先被执行。Bootloader是一个预先在STM32内部ROM中烧录的小程序其主要任务包括初始化硬件设备、设置系统时钟、配置内存等。  程序加载Bootloader完成启动后会开始加载用户程序。该程序通常存储在内部的Flash内存或者外部的存储设备中。程序被加载到SRAM中执行。如果用户程序存储在Flash中Bootloader可以直接跳转到Flash的起始地址开始执行。  主循环用户程序通常会包含一个主循环main loop在这个主循环中程序会周期性地或者根据特定事件执行特定任务。例如它可能会每隔一段时间读取一个传感器的数据或者当接收到一个网络包时进行处理。  中断处理在程序运行过程中可能会发生各种中断比如定时器到期、外部引脚状态变化、接收到串口数据等。当中断发生时CPU会停止当前的任务跳转到对应的中断服务程序进行处理处理完毕后再返回到原来的任务继续执行。  
4.1 keil编译后HEX文件内容解读 要实现串口下载功能就得先知道烧录程序HEX或者BIN文件究竟是个什么东西。关于HEX我以前也写过相关文章可以跳转一下 
STM32的hex文件格式的分析-CSDN博客 
关于BIN目前还未过深的了解印象中是二进制版本的HEX文件。 
4.2 如何实现程序跳转 STM32的程序实际上就是从FLASH地址由上到下根据指令内容跳转到FLASH相应地址继续执行的而已。 
因此如果我们要实现从bootloader跳转到我们flash写入的地址如何实现呢这里给个bootloader跳转到用户程序的参考例子 
#define FLASH_SAVE_ADDR  0x08020000		//设置 FLASH 地址(必须为偶数且其值要大于本代码所占用FLASH的大小0X08000000)
typedef  void (*iapfun)(void);			//定义一个函数类型的参数.//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(uint32_t addr) {MSR MSP, r0 			//set Main Stack valueBX r14
}iapfun jump2app; //跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(uint32_t appxaddr) {if(((*(__IO uint32_t*)appxaddr)0x2FFE0000)0x20000000) 	//检查栈顶地址是否合法.{ jump2app(iapfun)*(__IO uint32_t*)(appxaddr4);		//用户代码区第二个字为程序开始地址(复位地址)		MSR_MSP(*(__IO uint32_t*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)jump2app();									//跳转到APP.}
}int main(void) {//判断是否 PA5 按键状态按下则跳转到 FLASH_SAVE_ADDR 地址运行另外一个程序if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)  RESET) {iap_load_app(FLASH_SAVE_ADDR);//跳转执行FLASH_APP代码}
} 
我们烧写的用户应用程序则需要注意修改一下地址便宜 根据实际需要进行修改。图中Start地址与#define FLASH_SAVE_ADDR保持一致。图中Size大小则应该是0x8040000-Start地址。 
并且修改Flash地址偏移在main首句或之前赋值即可 
SCB-VTOR  FLASH_BASE | 0x20000; //内部FLASH的向量表重定位 根据实际需要进行修改。这偏移值应该是 Start地址-0x8000000。 
4.3 如何实现对STM32内部Flash的写入 STM32的标准库有对FLASH操作的API可以使用这些API对FLASH进行操作。其大致流程如下 解锁Flash在写入Flash之前首先需要对Flash进行解锁。STM32的Flash有写保护功能为了防止意外操作导致的数据损坏需要手动解除保护。解锁操作需要向特定的解锁寄存器如KEYR写入特定的密钥序列。  等待Flash就绪解锁完成后需要确保Flash处于就绪状态。可以通过检查FLASH_SR寄存器的相关位如BSY位来判断Flash是否处于忙碌状态。务必等待Flash就绪后再进行后续操作。  擦除目标扇区在写入数据之前需要先擦除目标扇区。STM32的Flash是按扇区进行擦写的擦除一个扇区会把该扇区的所有数据设置为全10xFF。擦除操作需要设置FLASH_CR寄存器的相关位并指定需要擦除的扇区。  等待擦除完成擦除操作需要一定的时间因此需要等待擦除完成。可以通过检查FLASH_SR寄存器的相关位如EOP位来判断擦除是否完成。务必等待擦除完成后再进行后续操作。  写入数据擦除完成后就可以开始向目标地址写入数据了。通常可以选择按字32位或半字16位进行写入。写入操作需要设置FLASH_CR寄存器的相关位并将数据写入到目标地址。  等待写入完成与擦除操作类似写入操作也需要一定的时间。因此需要等待写入完成。可以通过检查FLASH_SR寄存器的相关位如EOP位来判断写入是否完成。  锁定Flash写入操作完成后为了防止意外操作导致的数据损坏建议重新锁定Flash。锁定操作需要设置FLASH_CR寄存器的相关位如LOCK位。  
具体的开发实例可以参考野火或者正点原子的教程。笔者比较喜欢实用标准库因此喜欢实用野火的教程作为参考。 
4.4 实现的Bootloader展示 这里就不用过多篇幅去展示我的程序代码了有需要跳转下方链接自行下载包含上下位机 
基于stm32实现串口烧录程序资源-CSDN文库 大概说明一下笔者实现了开机时按下key1按钮待LED熄灭释放key1按钮即进入程序烧录模式。如按下的key2按钮将自动烧录在bootloader中准备好的点亮LED1的程序。收录完成后即会自行跳转到用户应用程序。 笔者这示例用户应用程序是从地址0x8010000开始的size为0x30000。 需要先进入烧录模式再启动python脚本进行程序烧录。因为只是测试用例并未设计得太用户化。 
5 总结 bootloader的功能并不止程序更新这一种还应该包括开机自检等功能不过这些功能都需要结合实际情况进行开发了笔者也就不再过多叙述。这此实验算是解开了笔者从前对arduino的一些疑惑有不少的收货和感悟。