
在我的项目中,我使用
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连接。
说明:
另一点细微差别。 在上传固件之前,您需要运行引导程序。 最简单的方法是按下重置按钮。 之后,引导加载程序将启动,并等待几秒钟以获取固件。 如果此时没有人启动maple_upload,则引导加载程序会将控制权转移到主固件。
为了避免每次都按下reset键,基于libmaple / stm32duino的主板使用了一个技巧。 他们听USB串行端口。 如果在那里出现DTR信号并发送了关键的字节序列,则微控制器将重新加载到引导加载程序中。 查看
rxHook()函数 。
这可能会带来不便。 如果微控制器关闭并挂起,则它不再侦听端口。 因此,他无法听到按键顺序并重新启动到引导加载程序中。 然后仅重置以提供帮助。
仅此而已。 我希望我的文章能够阐明Bootloader在STM32中的工作方式以及如何通过USB端口下载固件。 不幸的是,进入门槛仍然很高,但突然我的文章将帮助某人克服它。