目录

  • 一、前言
  • 二、CubeMX生成 IAR 工程
    • 1.CubeMX生成工程
    • 2.官方的IAP例程
  • 三、移植bootloader
    • 1.移植相关代码
    • 2.flash_if.h文件修改
    • 3.准备App程序
    • 4.烧录*.bin
  • 四、调试及其他注意事项
    • 1.中断向量表偏移没设对
    • 2.进入App后时钟起不来或时钟混乱
    • 3.在bootloader的工程里怎么调试app程序

一、前言

产品发布后的升级不能再依赖于烧录器,如果能用产品预留的串口就可以更新芯片的APP程序,对于一些不便于拆卸的产品,这种维护方式非常好用。

bootloader的代码有很多选择,比如正点原子的bootloader 和 RT-thread 官方的bootloader。
作者选用ST官方提供的bootloader,使用Ymodem协议传输。

bootloader的工作原理这里不展开说,总结下来就是把bootloader的程序写到原来的0x08000000,而主程序作为App程序,往0x08008000地址烧录,bootloader里提供三个功能,一个是往0x08008000里烧录App,一个是下载0x08008000里的程序,一个是跳转到0x08008000 App程序。
当然刚上电是先进入bootloader,再跳转App。

二、CubeMX生成 IAR 工程

1.CubeMX生成工程

在CubeMX除了选择MCU还可以选择开发板的,有限官方的开发板自带了IAP例程,也就是bootloader。

Toolchain/IDE 选择EWARM就是生成IAR工程了。注意要配置好烧程序用的串口。

2.官方的IAP例程

只有默写板子有IAP例程,可以去安装包Applications的这个路径下找到IAP文件夹。

这是个文件和对应的头文件就是用到的,另外main 函数里有写进入menu.c 的入口函数,也可以复制到自己的程序中。

三、移植bootloader

1.移植相关代码

将bootloader相关的.c和.h 文件加入工程后就编译一下,如果报有缺少头文件添加一下。
注意下面几个函数:
1.Serial_PutString()函数

这个是代替printf用的(printf文件比较大一般bootloader不使用),这个函数在common.c中,注意修改官方例程中的串口为你的烧录串口,比如你CubeMX 配置的是UART_HandleTypeDef huart1,就把用到串口的地方都改成huart1。

2.Main_Menu ()函数
这个是进入bootloader菜单选择的函数,可以看到串口输入1,2,3,4分别有不同的功能,其中1是烧录app,3是跳转app。

void Main_Menu(void)
{uint8_t key = 0;Serial_PutString((uint8_t *)"\r\n======================================================================");Serial_PutString((uint8_t *)"\r\n=              (C) COPYRIGHT 2016 STMicroelectronics                 =");Serial_PutString((uint8_t *)"\r\n=                                                                    =");Serial_PutString((uint8_t *)"\r\n=          STM32F4xx In-Application Programming Application          =");Serial_PutString((uint8_t *)"\r\n=                                                                    =");Serial_PutString((uint8_t *)"\r\n=                       By MCD Application Team                      =");Serial_PutString((uint8_t *)"\r\n======================================================================");Serial_PutString((uint8_t *)"\r\n\r\n");while (1){/* Test if any sector of Flash memory where user application will be loaded is write protected */FlashProtection = FLASH_If_GetWriteProtectionStatus();Serial_PutString((uint8_t *)"\r\n=================== Main Menu ============================\r\n\n");Serial_PutString((uint8_t *)"  Download image to the internal Flash ----------------- 1\r\n\n");Serial_PutString((uint8_t *)"  Upload image from the internal Flash ----------------- 2\r\n\n");Serial_PutString((uint8_t *)"  Execute the loaded application ----------------------- 3\r\n\n");if(FlashProtection != FLASHIF_PROTECTION_NONE){Serial_PutString((uint8_t *)"  Disable the write protection ------------------------- 4\r\n\n");}else{Serial_PutString((uint8_t *)"  Enable the write protection -------------------------- 4\r\n\n");}Serial_PutString((uint8_t *)"==========================================================\r\n\n");/* Clean the input path */__HAL_UART_FLUSH_DRREGISTER(&huart1);/* Receive key */HAL_UART_Receive(&huart1, &key, 1, RX_TIMEOUT);switch (key){case '1' :/* Download user application in the Flash */SerialDownload();break;case '2' :/* Upload user application from the Flash */SerialUpload();break;case '3' :Serial_PutString((uint8_t *)"Start program execution......\r\n\n");/* execute the new program */JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);/* Jump to user application */JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();break;case '4' :if (FlashProtection != FLASHIF_PROTECTION_NONE){/* Disable the write protection */if (FLASH_If_WriteProtectionConfig(OB_WRPSTATE_DISABLE) == HAL_OK){Serial_PutString((uint8_t *)"Write Protection disabled...\r\n");Serial_PutString((uint8_t *)"System will now restart...\r\n");/* Launch the option byte loading */HAL_FLASH_OB_Launch();/* Ulock the flash */HAL_FLASH_Unlock();}else{Serial_PutString((uint8_t *)"Error: Flash write un-protection failed...\r\n");}}else{if (FLASH_If_WriteProtectionConfig(OB_WRPSTATE_ENABLE) == HAL_OK){Serial_PutString((uint8_t *)"Write Protection enabled...\r\n");Serial_PutString((uint8_t *)"System will now restart...\r\n");/* Launch the option byte loading */HAL_FLASH_OB_Launch();}else{Serial_PutString((uint8_t *)"Error: Flash write protection failed...\r\n");}}break;default:Serial_PutString((uint8_t *)"Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r");break;}}
}

3.Ymodem_Receive() 函数

这个函数是执行Ymodem传输协议功能的,参考https://blog.csdn.net/INT_TANG/article/details/117334848

2.flash_if.h文件修改

修改USER_FLASH_END_ADDRESS(片内Flash结束地址),和APPLICATION_ADDRESS(App起始地址),这里改成0x08008000,0x08000000~0x08007FFF用于存放bootloader(Note: the 1st sector 0x08000000-0x08007FFF is reserved for the IAP code)

/* End of the Flash address */
#define USER_FLASH_END_ADDRESS        0x080FFFFF
/* Define the user application size */
#define USER_FLASH_SIZE   (USER_FLASH_END_ADDRESS - APPLICATION_ADDRESS + 1)/* Define the address from where user application will be loaded.Note: the 1st sector 0x08000000-0x08007FFF is reserved for the IAP code */
#define APPLICATION_ADDRESS   (uint32_t)0x08008000

这些修改好可以编译跑一下看看bootloader的输出是否正常。

3.准备App程序

bootloader使用Ymodem下载时用的是bin文件,IAR中要修改ROM起始地址,中断向量起始地址和输出文件。


4.烧录*.bin

然后就可以在SecureCRT里调用Send Ymodem来烧录这个*.bin程序了。

移植参考 https://blog.csdn.net/INT_TANG/article/details/117235294 IAR和Keil工程的操作都是一样的。

四、调试及其他注意事项

1.中断向量表偏移没设对

如果debug的时候发现程序进入hard fault大概率是中断向量表没设对,在程序最开始加上下面的这段把向量表的起始地址强制设为App的起始地址。

SCB->VTOR=0x08008000;

2.进入App后时钟起不来或时钟混乱

官方手册上说:一旦启用了PLL,就无法更改主PLL配置参数,因此建议在启用PLL之前先对其进行配置(选择HSI或HSE振荡器为PLL时钟源,以及除法因子M,P,Q和乘法因子N的配置)。

也就是说PLL在启动之后便不能够重新配置。可以先把时钟改为内部时钟然后再配置PLL。

参考 https://blog.csdn.net/xiaoyuanwuhui/article/details/108772487

3.在bootloader的工程里怎么调试app程序

只能看Flash里反汇编的程序,一步步反推app哪里出现了问题。
IAR里看PC寄存器的值() PC指向当前程序运行的地址,跑到0x08008000以后就是进入App程序了。
然后通过看Disassembly反汇编查看对应的App的C程序在哪一行出现问题了。
App生成bin文件和hex文件也可以生成汇编文件的,用这里的反汇编和App的汇编文件去对比。

stm32f4 CubeMX生成IAR工程 移植ST官方 Bootloader 教程相关推荐

  1. cubeMX生成AC6工程,无法调试!!!

    一.前言 由于之前采用KEIL开发,但是由于KEIL的编辑功能实在是太差了,偶然的机会,发现ST官方,有提供自己的开发工具(AC6).实际上是ST公司基于ECLIPSE针对STM32开发的一个插件,E ...

  2. DW1000开发笔记(三)基于STM32 HAL库裸机工程移植DW1000官方驱动

    系列文章 DW1000开发笔记(一)DW1000芯片概览 DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信 一.官方驱动 Decawave官方提 ...

  3. stm32mp157系统移植 | 移植ST官方5.10内核到小熊派开发板

    Linux内核移植流程 移植Linux内核到一个新的板子上时,需要以下步骤: (1)选择一个硬件设计接近的板子,基于此板相关文件开始移植 (2)拷贝单板配置文件(arch/arm/configs) ( ...

  4. CubeMX生成的STM32F4xx MDK工程FPU和DSP库的使用

    CubeMX生成的STM32F4xx MDK工程FPU和DSP库的使用 STM32F4xx属于Cortex M4F架构,带有32位的单精度硬件FPU(Float Point Unit),支持浮点指令集 ...

  5. STM32 IAR工程-Keil MDK转换详解

    我在 STM32 的学习中发现,大部分的STM32示例程序都是基于IAR开发环境的,但我认为使用 Keil  MDK开发环境更加方便,可以利用RVMDK强大的外设仿真功能加速STM32的开发.我在以前 ...

  6. STM32L051测试 (一、使用CubeMX生成工程文件 — ST系列芯片通用)

    本文也适合STM32CubeMX 支持的所有芯片的设置 ..调整文章结构,添加图文说明 2022.2 ..增加其他应用章节,增加 ADC 设置说明 2023.3 CubeMX生成工程步骤 前言 一.时 ...

  7. 单片机 STM32F103C8T6 cubeMX HAL库 从环境到开发 正点原子工程移植 freeRTOS

    文章目录 0 准备材料 1 闪烁PC13的小灯 2 正点原子工程移植 注意点以及细节 3 freeRTOS 3.1 LED KEY 串口1 的一个实验 0 准备材料 1.需要正点原子的HAL介绍书籍可 ...

  8. 基于STM32F4移植W5500官方驱动库ioLibrary_Driver(转)

    源: 基于STM32F4移植W5500官方驱动库ioLibrary_Driver 参考: 基于STM32+W5500 的Ethernet和Internet移植 Upgrade W5500 Throug ...

  9. IAR中移植UCOS II系统以及sourceInsight 使用

    ucos 学习笔记 1 sourceInsight 使用 CSDN参考链接 新建工程 第一步:project中new project 第二步:在高亮部分输入工程的地址,工程文件夹与IAR工程文件夹放在 ...

最新文章

  1. hashmap value可以为空吗_美团面试题:Hashmap结构,1.7和1.8有哪些区别(最详细解析)...
  2. centos添加新硬盘
  3. 面试:说说你对“零拷贝”的理解?
  4. 求android实现未读短信图标数字提示效果
  5. 深度学习Deep learning:四十一(Dropout简单理解)
  6. Java学习--多态
  7. ASP.NET Core中使用GraphQL - 第一章 Hello World
  8. 《编码规范和测试方法——C/C++版》作业 ·002——函数返回地址、static关键词用法整理
  9. 国产杀毒软件连续因“作弊”遭全球权威评测机构指责
  10. Android安全-代码安全4-逆向工具对抗
  11. 腾讯地图点聚合开发-实现地图找房功能
  12. 区块链开发基础知识学习
  13. linux环境做路径左斜杠和右斜杠,不同操作系统下的路径分隔符—反斜杠与斜杠...
  14. outlook邮件通过python发送_怎么发送邮箱-python调用outlook发送邮件的超详细操作步骤...
  15. 区块宝周报:区块链一周大事排行榜10.16
  16. 【前端html页面数据导出为pdf文件】
  17. 自动识别查找特定的串口号 比如设备管理器中Modem属性里的串口 按这个方法可以获取设备管理器任意信息。C++
  18. 【java】JavaFX从零开始实现拼图小游戏
  19. Linux驱动——mmc sd card初始化流程(十一)
  20. 基于爬虫+人脸识别库实现指定人物自动采集

热门文章

  1. Linux 打包压缩-文件打包-打包工具【tar】命令使用简介
  2. 2018焦作ICPC E - Resistors in Parallel(规律+Java大数)
  3. 「GoCN酷Go推荐」go语言位操作库 — bitset
  4. 国产ARM核心工控主板介绍
  5. C语言一些常用的代码(初学者,随缘更新)
  6. 时延、时间带宽积、RTT、利用率
  7. 研究生入门工具——让你事半功倍的SCI、EI论文写作神器
  8. Win32ASM学习[16] :乘除指令: MUL、IMUL、DIV、IDIV
  9. 基本不等式凸函数拉格朗日乘子
  10. mysql倒序分页,90%的人看完都说好