[align=center][align=center]完整内容请下载附件
[align=center]Bootloader跳转到RT-Thread或FreeRTOS(基于STM32)[align=center]作者:猾蚁 QQ:7376220[align=center]一、Bootloader程序[align=center]1.准备好升级程序项目,可以使用STM32CubeMX来自动生成代码,然后自己编写代码实现升级策略。[align=center]2.跳转代码实现[align=center]Main.c[align=center]#define BOOT_LOADER_Address 0x08000000 [align=center]#define BOOT_LOADER_SIZE (2001024) //0x32000(200KB)[align=center]#define BOOT_OS_Address (BOOT_LOADER_Address+BOOT_LOADER_SIZE)[align=center]typedef void (pFunction)(void);[align=center]pFunction Jump_To_Application;[align=center]uint32_t JumpAddress;[align=center]static void jump_to_os(void);
[align=center]//重定向printf[align=center]int fputc(int ch, FILE f)[align=center]{ [align=center] while((USART1->SR&0X40)==0);[align=center] USART1->DR = (uint8_t) ch; [align=center] return ch;[align=center]}[align=center]int main(void)[align=center]{[align=center]HAL_Init();[align=center]SystemClock_Config();[align=center]MX_USART1_UART_Init();
[align=center]//在这里实现升级策略[align=center]printf(“user_init()
“);
[align=center] //升级完成后程序跳转到RT-Thread[align=center] jump_to_os();[align=center]}[align=center]static void jump_to_os(void)[align=center]{[align=center] if ((((IO uint32_t)BOOT_OS_Address) & 0x2FFE0000 ) == 0x20000000)[align=center] { / Jump to user application */[align=center] printf(“jump_to_os
“);[align=center] [align=center] disable_irq() ; //关闭总中断[align=center] HAL_DeInit();[align=center] [align=center] JumpAddress = (__IO uint32_t) (BOOT_OS_Address + 4);[align=center] Jump_To_Application = (pFunction) JumpAddress;[align=center] / Initialize user application’s Stack Pointer /[align=center] set_MSP(*(IO uint32_t) BOOT_OS_Address); [align=center] Jump_To_Application();[align=center] }[align=center] else[align=center] {[align=center] printf(“BOOT_OS_Address:%08X
“, (__IO uint32_t*)BOOT_OS_Address);[align=center] } [align=center]}
[align=center]3.Keil设置
[align=center]上面的IROM1的Size设置与前面宏定义BOOT_LOADER_SIZE值相同,值为十六进制
[align=center]这里的Start、size和前面的IROM1设置相同
[align=center]编译后下载,因为前面未选择Reset and Run,下载完成后程序不会运行。
[align=center]二、RT-Thread程序[align=center]1.准备好RT-Thread项目,确认项目可成功编译运行。[align=center]2.重定义中断向量表地址[align=center]找到stmtem_stm32fnxx.c文件中的SystemInit函数,找到SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET这一句,转到VECT_TAB_OFFSET的宏定义,修改值为前面BOOT_LOADER_SIZE的值:#define VECT_TAB_OFFSET 0x32000[align=center]3.启用SystemInit函数,使上面中断向量表重定义生效[align=center]SystemInit函数没有被任何C代码调用,它在启动汇编代码中被导入调用。启用startup_stm32fnnnxx.s文件中SystemInit被调用的相关代码(去掉分号注释即可),启用后如下图:
[align=center]4.Keil设置
[align=center]IROM1的Start设置为前面BOOT_OS_Address定义的值,size设置为MCU的Flash总大小减去BOOT_LOADER_SIZE后剩余的大小。
[align=center]这里的Start、size和前面的IROM1设置相同
[align=center]编译后下载,如果上面选择了Reset and Run,下载完成后程序会从Bootloader开始运行,实现程序升级过程后跳转到RT-Thread运行,如下图:
[align=center]