通过USB将固件下载到STM32

图片

在我的项目中,我使用STM32F103C8微控制器stm32duino框架 。 Arduino的此克隆提供了一种特殊的引导程序,可让您通过USB上传固件,而无需使用ST-Link或USB-UART适配器之类的外部组件。

今天,我需要使用CooCox下的裸控制器,并且没有stm32duino。 但这是问题所在。 即使是通过该引导加载程序注入的简单的指示灯也无法正常工作。

让我们做对。 也许我的计算似乎很平常。 但是我才刚刚开始研究STM32控制器,并且至少花了半天时间才发现问题。 突然,本文将缩短某人的开发时间。

我对ST-Link和其他调试器一无所知。 但是在我完成的设备中不会,但是肯定会有USB。 为什么不立即放弃通过USB更新固件的功能? 我个人觉得这种方法很方便。 无论如何,我已经连接了电源和USB串行线。

让我们看看引导加载程序是如何工作的。 首先介绍AVR控制器的示例。 我为什么还记得他? 我从Arduino切换到了下意识地期望相同的行为。 但是在STM32中,一切都不同了。 因此,我想谈谈这两个微控制器之间的区别。

这样啊 在AVeg ATMega微控制器中,可以在闪存快要结束时为引导加载程序保留一定数量的内存。 使用熔丝位,您可以控制程序从哪个地址开始。 如果没有引导程序,程序将从地址0x0000开始。 如果有引导加载程序,它将从其他地址开始(例如,如果引导加载程序大小为2k,则在ATMega32中为0x3C00)。

图片

引导加载程序完成其工作后,它将控制权从地址0x0000转移到主程序。 即 程序始终从0x0000开始。 编译器和链接器的工作原理是,代码将位于地址空间的开头。

在STM32微控制器中并非如此。 所有程序均从地址0x0800000开始。 引导加载程序不是很特别。 这是从相同的起始地址开始的相同程序。 在此过程中,引导加载程序可以接收固件(通过USB或UART,从USB闪存驱动器读取,从卫星接收,从子空间获取固件,等等)并将其写入高于引导加载程序本身的地址。 并且,当然,在他的工作结束时,将控制权转移到主程序。

图片

因此,在编译固件时,您需要知道引导加载程序将固件写入何处并相应地调整地址。

理论上就是这样。 让我们继续练习。 下面是有关如何将USB Bootloader固定到STM32F1xx系列微控制器以及其他一些固件的分步说明。

但是,电路存在一些限制。 在这里,不幸的是,我并不坚强。 ITP的PA12端口(又称USB D +)需要一个1.5k的上拉电阻。 这允许引导加载程序在正确的时间连接和断开USB连接。

说明:

  • 下载github.com/rogerclarkmelbourne/STM32duino-bootloader 。 在STM32F1 \ binaries目录中,已经有用于不同电路板的已编译引导加载程序包。 文件名末尾的索引指示LED的连接位置。 如果板上的LED连接到C13引脚,则使用文件generic_boot20_pc13.bin。

  • 我们按照说明进行闪烁。 是的,在这里您将需要一个USB-UART适配器,但是您也可以使用调试器

  • 现在,微控制器已准备好通过USB引导加载程序进行刷新。 但是您仍然需要修复固件本身。 您需要做两件事:

    • 给链接器一个开始地址。 在CooCox中,这是在项目设置,“链接”选项卡,“内存区域”部分,“ IROM1起始地址”中完成的。 引导加载程序占用前8 KB,这意味着固件的起始地址将为0x0800000 + 0x2000 = 0x08002000。 “大小”字段可能也应减少8k。

    • 在程序开始的某个地方,在初始化外围设备之前,先打电话

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000); 


      更新2018年5月17日:在现代版本的STM32Cube中没有NVIC_SetVectorTable()函数。 相反,您可以在文件system_stm32f1xx.c中修复缺陷VECT_TAB_OFFSET(或对于其他微控制器类似)

  • 可以从stm32duino项目获取固件。 在工具目录中,查找一个名为maple_upload的脚本。 我只使用Windows版本-maple_upload.bat。

  • 像这样运行:

     "maple_upload.bat" COM20 2 1EAF:0003 "Path\To\Firmware.bin" 

    代替COM20,您需要替换连接微控制器的端口。

    倒酒是非常温柔的事情,它不喜欢相对路径。 因此必须完全指定固件的路径。

    1EAF:0003是VID和PID

    2-这是AltID参数,它指示固件应该在0x08002000上载( 在此处阅读)。

另一点细微差别。 在上传固件之前,您需要运行引导程序。 最简单的方法是按下重置按钮。 之后,引导加载程序将启动,并等待几秒钟以获取固件。 如果此时没有人启动maple_upload,则引导加载程序会将控制权转移到主固件。

为了避免每次都按下reset键,基于libmaple / stm32duino的主板使用了一个技巧。 他们听USB串行端口。 如果在那里出现DTR信号并发送了关键的字节序列,则微控制器将重新加载到引导加载程序中。 查看rxHook()函数

这可能会带来不便。 如果微控制器关闭并挂起,则它不再侦听端口。 因此,他无法听到按键顺序并重新启动到引导加载程序中。 然后仅重置以提供帮助。

仅此而已。 我希望我的文章能够阐明Bootloader在STM32中的工作方式以及如何通过USB端口下载固件。 不幸的是,进入门槛仍然很高,但突然我的文章将帮助某人克服它。

Source: https://habr.com/ru/post/zh-CN403007/


All Articles