
我们做STM32产品开发,最终是要将编写的程序代码写进芯片存储器,通常指Flash存储器【含可以映射到芯片存储空间的片外存储器】,让程序正常运行起来以实现相应的功能。, Z8 H( Q& }8 C2 w% E9 e % c9 Y" u% Q! D3 i n 一般来讲,将我们准备好的机器代码HEX或BIN文件等写进片上FLASH可以有三种常用的烧写方式。【温馨提示:下面提到的烧写方式的术语或称谓不是绝对的,对于不同的器件可能有不同的表述甚至内涵,这里仅针对STM32,知道怎么回事就好】1 w+ G; r7 `5 W$ u9 @ $ g3 @0 I, B p- X 4 [5 c# l8 a& X! ^ 第一种,ICP【In circuit programming】,即在电路编程或在线编程【注:不必太纠结该术语名字或称谓。平常称之为ICP也挺好】。一般是指利用调试器通过调试接口将程序代码写进芯片存储器的过程。调试器可以是ST官方的STLINK或其它公司的产品,比如JLINK,ULink等。 这里的调试端口可以是SWD或JTAG接口。3 ~+ v& ]% V( ?# S0 C+ p % @ H7 U* a% I4 B2 W: j8 h / |6 @' E+ i& ?& e, |- u" N S 针对ICP编程方式,ST官方有提供相应的软件工具,比如STLINK_Utility或STM32cbueProgrammer。至于其它公司的调试器,也有配套的软件工具。! X0 _* l) q7 w' A + l. j+ u1 h$ N+ i/ A ![]() ' X' W4 }( S) _. j& u. y8 \0 o 第二种,IAP【In application programming】,即在应用编程。一般是指芯片里已经存在具有升级更新功能的代码在里面了,用户基于该部分功能代码再将另外的程序代码写进芯片存储器的过程。也就是说芯片里平常有两套代码,一套用于实现代码的更新升级,往往称之为用户引导代码或启动代码。另外一套就是芯片平常运行的功能代码,我们称之为用户应用代码。 0 g3 G5 D( e) g1 L 第三种,ISP【In system programming】,即在系统编程。我们可以把该模式看做一种特殊的IAP模式,只是片内的启动代码是由芯片厂家这个特定用户出厂时写好提供的。一般来讲该段代码位于特定存储位置、用户不可更改。* Q! _) }* N- Z$ u- \# i # c* L" o+ A+ ]# X$ { 我们使用ISP方式编程的话,可以选择内嵌系统启动代码认可的通信接口,比如USART,I2C,SPI,CAN,USB等,借助于芯片厂家或第三方提供的软件工具来实现。具体到STM32系列芯片,欲利用ISP方式进行编程烧写的话,软件工具可以使用ST官方提供的Stm32CubeProgrammer。+ L( S) L# T, G E ![]() 对于STM32芯片的ISP方式烧录编程,往往需要对硬件BOOT脚做合适的电平设置,以及对选项字进行正确配置,确保芯片从系统存储区启动、运行。另外,烧录完毕后,记得将相关BOOT脚电平进行调整,以保证下次芯片启动后运行在正确的程序空间,一般是指调整回芯片主程序区。 上面介绍了ICP和ISP烧录所涉及的软件工具。至于IAP,程序的更新升级就是基于MCU现有的通信接口并借助用户之前写进芯片的启动代码来完成。比方,用户通过UART接口借助于内部引导程序来完成应用程序的更新。这里可能会有人会问,那用户准备的启动程序如何写进芯片呢?显然,我们可以通过ICP方式或ISP方式来完成用户启动代码的事先烧写。 ( p& w) O) V$ i$ E 下面是三种烧写方式的一个简单比较汇总表。三种方式各有特点.。表格中提到的无特定软硬件接口需求是相对的,意思是指基于芯片现有常用接口和通用软硬件工具,比方串口调试助手等。其中IAP方式对特定软硬件的依赖性最弱,使用更为灵活。但开发工程师须多做一件事,即自己写用户引导程序。当然,对于STM32来讲,各个系列都有一些IAP例程供用户参考。而ICP方式往往是产品调试过程中最为常用的一种烧写方式。ISP方式是生产环节较为常用的一种代码烧写方式。7 k$ W) r3 }; w1 Q, W 4 `/ ]" w) m) E0 } / _! k) o) P; l9 Z+ [$ Z5 K/ r ![]() F3 D* a7 }' u0 A+ k- P 下面就STM32F746芯片使用ISP方式的烧写流程做个简单介绍,顺便做些提醒。 # Z' y7 m9 g- X. k* i9 u 一般来讲绝大部分STM32芯片都是支持ISP方式的。在选用这个烧写方式之前先确认下它是否支持ISP方式,即片内是否内置了system memory,该处存放着系统启动程序。我们可以通过各芯片所属的参考手册BOOT章节和AN2606应用笔记查看确认。, \- L# j0 f8 p# X4 A! X. l6 ] 经确认,STM32F746支持ISP,不妨选用UART3接口。【当然,它还支持其它通信接口】 # v( t4 e0 y, c1 J) g 查看其所对应的参考手册,了解使用ISP方式所需的配置。一般指BOOT脚的电平确定、选项字的配置。具体到这里,就是确定BOOT脚的电平和System memory的启动入口地址。8 W2 [+ s0 v+ r* }' v ![]() @% u! r m5 `5 M+ H) v 对于STM32F7而言,芯片的启动地址可以通过启动地址选项字节任意配置,且有两种配置方式,对应于BOOT脚的电平为高或为低时启动地址选项字节所给出的地址。其地址范围在0x0000 0000 to 0x3FFF FFFF之间。如果配置的地址越界,硬件将使用默认启动入口地址。 我们现在要使用system memory,故需找出它所在的地址范围,根据手册可以查到。9 T7 D0 L; W4 g* c' q& J+ r- r ![]() 8 X% X4 O/ l2 ]/ s9 x9 ^ M % A$ Y: D/ x( k; H 从上面表格得知,访问System memory可以有两个地址,分别源自不同的访问接口。 ) Q7 J& m# a6 K8 `- a! ] " X: t( R: n( J# @3 i1 P 我们不妨选用ICTM接口地址作为其入口地址,即0x00100000,将BOOT脚电平设置为高,则需配置BOOT_ADDR1【15:0】选项字节。这个选项字节是怎么拟定的呢?它是将程序启动入口地址的bit29~bit14对应过来的。比方我们选择system_memory的启动入口地址为0x0010,0000,则它所对应的选项字节数据就是0x0040。这点要弄清楚,否则当我们想通过修改启动地址选项字节来改变启动地址时就不知怎么填写数据了。( w- w N) P* t7 s1 r ! }3 n, w; i7 A+ E 当然,对于BOOT_ADDR0和BOOT_ADDR1都有默认值。BOOT_ADDR0的默认值是0080,对应于ITCM接口的0x00200000。BOOT_ADDR1的默认值是0040,即对应于ITCM接口的0x00100000,结合上面的介绍可知它刚好是system memory的入口地址。显然,对于一颗没有更改过BOOT_ADDR1的STM32F7芯片来说,欲使用ISP的话,只需将BOOT脚置高即可,无须再手动调整启动地址选项字节。# ~( ~; f) b# E7 P 7 A0 m5 ~& _* P5 X+ c5 Y+ J 2 `( _" R' O* j u8 F- L0 b2 _3 C3 @ 剩下的事情就是确认硬件线路、打开STM32CubeProgrammer、连机下载即可。当然下载前可以根据需要做好各自配置,比如读写保护、看门狗启动选择等。. p8 E9 D# C2 \4 l . Z" N0 K# I# Z2 _. V0 K$ i9 P& ` ![]() 再次提醒下,通过ISP烧写完毕后,记得调整BOOT脚的电平以保证芯片重启后运行主程序区的用户代码。- l0 j Q, Y. k! R, ?( ?9 r 总的来讲,基于ISP方式的STM32芯片烧写过程不复杂。最后一点建议,目标板上最好弄个复位键,操作方便点,如果板上不方便设计复位键,烧写工位上安排个也可以。基于STM32F746芯片使用ISP方式进行烧录就提醒这么多。毕竟说得再多,不如一试。$ P( o. E& b0 y. Z- j$ w$ B- U1 X 本文的主要目的就是让刚接触STM32的人对STM32芯片的烧写方式有个基本的了解,至于具体的实现,除了上面提到的基于ST的工具外,还有其它第三方的编程烧写工具可以选用。1 \& P$ r6 ? @. z! k + n6 z* q6 Y; q( q1 a, h |