写在前面:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
存储器采用固定的存储器映射,代码区域起始地址为 0x0000 0000
(通过 ICode/DCode 总线访问),而数据区域起始地址为 0x2000 0000
(通过系统总线访问)。Cortex-M3 CPU 始终通过 ICode 总线获取复位向量,这意味着只有代码区域(通常为 Flash)可以提供自举空间。STM32F1xx 微控制器实施一种特殊机制,可以从其它存储器(如内部 SRAM) 进行自举。
在 STM32F1xx 中,可通过 BOOT[1:0] 引脚选择三种不同的自举模式,如下图所示:
当复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。复位后,用户可以通过设置 BOOT1 和 BOOT0 引脚来选择需要的自举模式。
BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。
器件退出待机模式时,还会对 BOOT引脚重新采样。因此,当器件处于待机模式时,这些引 脚必须保持所需的自举模式配置。这样的启动延迟结束后,CPU 将从地址 0x0000 0000 获 取栈顶值,然后从始于 0x0000 0004 的自举存储器开始执行代码。
注意:如果器件从 SRAM 自举,在应用程序初始化代码中,需要使用 NVIC 异常及中断向量表和偏 移寄存器来重新分配 SRAM 中的向量表。
使用的是 STM32内置的 Flash,一般我们使用 JTAG或者 SWD模式下载程序时,就是下载到这个里面,然后重启后直接从 Flash中启动程序。
属于 STM32自带的 BootLoader,这种模式启动的程序功能是由厂家设置的;该模式下,只能通过官方给出的特定的串口或者 USB等专属引脚下载:
当使用该方式下载,可以通过这个官方的 BootLoader将程序下载到系统的 Flash中,因此,在下载完成后,需要通过 BOOT[1:0] 引脚更改为 Main Flash memory(BOOT1=x BOOT0=0)模式然后重新上电才能正常启动。
在该模式下启动程序,由于是利用内置 SRAM,那么根据 SRAM的特点,它是并没有程序存储的能力了 — 掉电丢失,但由于它读写速度快,以及没有刷写寿命,所以这个模式一般用于程序调试。
假设我只修改了代码中一个小小的地方,若是使用上面的其中一种模式,那么我需要重新擦除整个 Flash,然后再重新下载写入,这是比较的费时;而当从这个模式启动代码,由于 SRAM的特点,我们可以刷写程序并调试,更不用考虑是否会超出刷写次数,最后等到程序调试完成后,再将程序下载到 Flash中。
然后总的来说就是:
从官方列举的自举模式,可以看出,不管是哪个模式下 BOOT0的引脚必须是一个固定的电平,特殊的是 Main Flash memory模式下 BOOT1可以取 0 or 1,而不是浮空,所以最好的选择还是给它安排一个稳定的电平信号,而一般来讲是把它接地。
一般出现调试口下载失败这种情况,若果排除了硬件的因素,那么绝大多数情况是由于原固件中把调试接口禁用了,如果想了解调试接口禁用方式,可以看之前的文章 << STM32笔记之 SWJ(JTAG-DP和 SW-DP)>> ;额,继续说,先说简单的解决方式,那就是,把 BOOT0引脚拉高,进入非 Main Flash memory模式,BOOT1可以随意取 0 or 1,但尽量不要浮空,详细解释稍后说。。。;或者直接以 System memory模式用预留的专属下载口下载使能调试接口的程序。
可能您有看过有些 blog或者论坛在讲调试口下载失败后,可以通过在点击下载的一瞬间按复位引脚,可以以一定概率完成下载(当然,此处是处于 Main Flash memory模式,为什么是该模式,稍后说);但,这并不是一种有效的方法,至于为什么可以,这个也是跟调试口禁用有关。。。而且是跟它的默认状态有关,所以它可以下载的概率跟其触发启动有关;同样的,非硬件因素,都是在程序中把调试接口禁用了,才会导致调试口下载失败。依然详细解释 稍后说 第四小点说。
A、先解析第三小点,为什么在调试口下载失败后,可以通过在点击下载的一瞬间按复位引脚能以一定概率完成下载呢?如果有详细看之前的 << STM32笔记之 SWJ(JTAG-DP和 SW-DP)>> 文章的第四大点,可以了解到,当处于复位状态的时候,其调试口的引脚是可以使用,也就是说,从点击下载的一瞬间(开始发送相应的调试序列)到按复位引脚(程序准备执行)再到读取并执行 OTP配置的时间内,调试口的引脚是使能的,注意,调试口禁用 /使能是属于那种 option byte的一次性永久保存的。
B、介于第三小点的:下载的一瞬间按复位引脚进行概率性下载的粗暴操作的不现实性,当然是不会去选择这样操作啦。
从上面得知:调试口禁用 /使能是属于那种 option byte的永久保存的(但它并不在 option byte上),因此,想要重现使能调试口的调试下载功能,就必须在下一次烧录中把使能调试口配置的放到程序中执行;而对于第二点的把 BOOT0引脚拉高,进入非 Main Flash memory模式,实际上还是得分两种情况:
系统内编程(ISP),一种将可编程设备放入电路板后对其进行编程的技术;是已安装在一个完整的系统中,而不是要求用户先对芯片进行编程安装才让它进入编程系统;它允许将固件更新传递到微控制器和相关处理器的片上存储器中,而无需在电路板上进行专门编程处理,这样使得设计工作得到简化。
在该编程方式上,其固件更新引导程序是随着出厂,内嵌在芯片的某段存储空间上的,即 ISP要占用一定空间存放 ISP引导程序。
一般常见的有 PIC、AVR等这些老牌的芯片都是支持的。
补充:https://en.wikipedia.org/wiki/In-system_programming
在线编程(ICP),可能有些译为 “在电路编程”,但准确的来说是称作 “在线编程”!嘛,随你们喜欢吧,知道这是怎么一回事就好了。
ICP的编程方式,相对于 ISP来讲,它更倾向于软件式引导烧录,一般是通过下载官方最新版的软件程序,利用上位机去引导程序对芯片进行编程,而 ISP则是利用其出厂时内嵌在芯片的引导程序对芯片进行编程;因此,ICP并不占用程序存储空间。
ICP可能听说的比较少,但它确实存在,目前在 Nuvoton的芯片上是可以通过该门技术进行编程的。
补充:http://www.nuvoton.com.cn/support/technical-support/faq/d3e8cc25-04f1-11ea-b113-05daf7eedf03/
在线串行编程(ICSP)是一种增强的 ISP技术,最早是在 Microchip公司的 PICmicro一次性可编程(One-Time-Programmable, OTP)和 FLASH RISC微控制器(MCU)中实现。该技术仅使用两个 I/O引脚来串行输入和输出数据,使 ICSP易于使用,对微控制器的正常操作影响较小。
如今,人们会把系统内编程(ISP),也称为电路内串行编程(ICSP),所以目前大多数芯片所说的 ISP烧录,实际上准确的来讲就是 ICSP。
补充:http://ww1.microchip.com/downloads/en/devicedoc/30277d.pdf
应用内编程(IAP),是用户自己从结构上将 Flash存储区(Firmware)划分为两个存储区域(即 BootLoader和 Application);在设计固件程序时编写两个项目代码,第一个项目程序存放在 BootLoader区,不执行正常的功能操作,只执行对 Application代码的更新,而第二个项目程序存放在 Application区,用于执行实际的功能代码。
该编程方式的目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级,一般按理说只要能传输数据的通信口都能实现 IAP的功能,而常用的 IAP的通信口有许多种:UART、ETH、I2C、SPI等等,因此, IAP更多的是作远程升级固件;而不需要像前面那三种需要硬件烧录器进行烧录升级(专属的引导程序 -> 升级程序),它是属于自身升级,可以在系统中获取新代码并对自己重新编程(自身程序 -> 升级程序)。