一、BootLoader程序使用说明:# m! G0 J) n' d) S- _ * E( y% f7 `: p, t6 `1 e" g 1 BootLoader程序占用11K空间,BootLoader预留空间(0x08000000-0x08004000)。/ T" e# V7 e6 K* r# t 用户程序需要设置在0x08004000以后,也可使用分散加载的方法设置用户程序。 建议用ISP方式并添加写保护,防止BootLoader程序丢失,本BootLoader采用 一边读一边写的方法,不受内存大小限制。 2 先打开超级终端,设置好波特率,8位数据位,1位停止位,无校验,无流控 打开需要升级的程序文件,点击发送。RS485方式通讯一般设置波特率为" b- }' {6 {2 [( R! c 230400bps,TTL通讯则可设为921600bps。; b3 d& Y- ^. _1 d% d 3 给下位机上电,在上电500毫秒内,无通讯则跳转至用户程序。若下位机发送 大写'C',发现超级终端有文件发过来,则下位机的BootLoad程序以Y_Modem协议 接收升级程序文件,并将文件内容写入APP程序区,然后跳转至APP程序运行。 , P7 A2 U% [) S2 A 4 升级程序时,黄色LED灯闪烁,运行APP程序时,绿灯闪烁。BootLoad程序和APP程序都 开启了看门狗,若有故障,自动复位,红灯一闪而过。- |4 q W0 Q0 r W- }6 M/ a5 q1 G( C) c- q 5 跳转至APP程序前,需要关闭所有用到的中断,切记。* v# r+ J( a: d' j. g$ z + O1 Q% _* i: n# {6 p% Y5 ^# _, @# e 6 LED指示灯相关的IO脚没有初始化。 建议产品设计者添加状态LED指示灯:黄灯闪烁表示程序正在升级中, 绿灯闪烁表示正常工作中(LED指示灯在循环中闪烁,如果不闪烁表明死机), 红灯亮表示进入硬件意外挂起函数(如果有看门狗则会复位,否则不掉电一直死机)。+ e3 f1 \2 a* i# o! C 7 用户程序的中断向量偏移设置如下: NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);1 ], U2 j- ? e, A* e4 ? ; APP程序分散加载的例子' e6 M. U" P2 L2 G9 l, q ; *************************************************************+ P- U8 J4 c8 b$ E4 n ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* 6 Q% W* @1 ]* a9 I LR_IROM1 0x08004000 0x00040000 { ; load region size_region$ h$ c' g5 X' @ ER_IROM1 0x08010000 0x00040000 { ; load address = execution address5 N% _8 e( @8 Z+ h *.o (RESET, +First) *(InRoot$$Sections)0 b* r1 g5 ]' A3 @6 g! h .ANY (+RO) }) a* q- ?1 Q8 Q% |7 M2 P RW_IRAM1 0x20000000 0x00010000 { ; RW data .ANY (+RW +ZI) u5 t9 g+ | W% H }& P9 A" x4 x. {3 n ;EX_SRAM_DATA 0x68000000 UNINIT 0x00020000 { ; RW data ; main.o (exsram) ; exsram 内存段名称* ~6 r3 } h1 f2 K# l _7 j ;}! v4 z3 p" Z1 S. N) Y7 ^' b M6 O& X } . R1 f2 n& W/ E8 x [ 6 _! ?, a& B* i) F7 { 7 N* g7 N9 F2 v2 z( k. L. g 二、工程说明* X/ N, r% I$ ~: f" w, z2 ] & M R" t9 A/ y 本工程是为实现RS485及CAN的IAP而设计的BootLoad程序,附带了以下几种固件库的% Y5 y, P E0 @% T* u 应用代码: RS485,CAN,FSMC,SPI,TIM,AD " S6 T7 V! N7 r Project Targets 设置说明 ( s& j; ` N- ]: s8 ~) b 1.Debug in Ram; ^* S) @3 `1 |4 H7 z+ {6 W9 r 9 i# U: `+ ?/ m$ c 在内存中运行和调试程序,避免Flash的反复擦除和写入,减少芯片寿命 在Option for 'Debug in Ram'\C/C++\Preprocessor Symbols\Defin 编辑框 增加VECT_TAB_RAM宏定义, nvic.c的NVIC_Configuration函数中增加如下代码, x, S; U8 s7 H) }' k" q2 {/ r& c. i 4 m' d% |- g% @$ Y; R. }0 ? #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 2 q) |' p0 [3 s- W. R) x #endif' k/ `8 p' W; n9 l 这样就把中断向量地址转移到Ram中 $ A& Q' M9 N2 f) d8 A5 m2 y; w 点击Option for 'Debug in Ram'\Utilities\Configure Flash Memu Command\Settings 在Cortex-M Target Driver Setup对话框, 8 r5 F( ]' J+ r- p3 Q3 i, U 选择Flash Download为Do not Erase,Program,Verify; I7 v0 k3 j2 J$ v8 k; \! F( p 分配程序空间和数据空间为0x20000000以后, 程序空间在前, 数据空间在后 IRAM_EXSRAM.sct 分散加载文件:! q% {+ k8 t3 s4 l ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* * ?4 O* ^* I2 G3 M4 h LR_IROM1 0x20000000 0x0000A000 { ; load region size_region ER_IROM1 0x20000000 0x0000A000 { ; load address = execution address2 H0 z$ ~; D1 V% Y( ~ *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO): {! |+ [; O+ v+ w3 R$ C9 H } RW_IRAM1 0x2000A000 0x00010000 { ; RW data+ g) H1 u3 ?2 W! R6 m .ANY (+RW +ZI) }* }+ ^! c; `: e3 f. V9 g% h1 Y' m* D RW_RAM1 0x68000000 0x00020000 { ; RW data .ANY (EX_SRAM) ; EX_SRAM 是声明的内存段名称 } } RAM.ini 程序放在内部SRAM中进行硬件仿真的初始化文件: # y- X ]9 g, R4 A, c% N) h SP = _RDWORD(0x20000000); // Setup Stack Pointer* D! B, Z) n- b PC = _RDWORD(0x20000004); // Setup Program Counter3 ?6 A) C, a" K2 W [% l; m _WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register % X1 a5 D. J# K- U 2.Debug in Flash) P o* _2 i+ @ 0 z: o& C0 B+ s8 g; K! T3 l7 G9 j 在Flash中运行和调试程序,需要对Flash的反复擦除和写入 5 k/ G4 g3 ^9 k3 I FLASH_EXSRAM.sct 分散加载文件:! Z p$ O% c5 N, Q ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* n" X- _, R( ?& N0 L7 J7 g8 O LR_IROM1 0x08000000 0x00040000 { ; load region size_region: T$ N u2 v# j1 R ER_IROM1 0x08000000 0x00040000 { ; load address = execution address* k3 u( H9 p) B6 t' j+ R7 t$ b7 f *.o (RESET, +First)3 p1 O$ K+ {$ L$ f& F *(InRoot$$Sections)- Z4 m' P* M2 H: s/ f5 t/ ~ .ANY (+RO)" C- X) |! v! [6 q0 d& c6 O } RW_IRAM1 0x20000000 0x00010000 { ; RW data .ANY (+RW +ZI) } EX_SRAM_DATA 0x68000000 UNINIT 0x00020000 { ; RW data main.o (exsram) ; exsram 内存段名称. F' S! P: Z1 ]! @ } } 注意: exsram全局变量只能在main.c或 main.h中定义,UNINIT表示不初始化 SIM_MAP.ini 软件仿真的初始化命令,将区域(0x68000000,0x68020000)设为可读可写: map 0x68000000,0x68020000 read write exec 1 e$ [- J$ ?8 b/ y5 a1 @7 w 5 B9 Z& n+ \2 J9 U$ v9 z: g 三、源代码组织架构 6 [* }' J' M5 G6 ?. Z/ L 文件夹名称: STM32F10x_BootLoad_IAP $ P# D& J I+ B( Q 固件库版本: V3.6.1 文件目录结构:/ f* e" Z% M2 |8 Y/ J9 S7 g STM32F10x_BootLoad_IAP% B; J1 n4 y2 V0 P, L3 e) M' }' v1 R │4 q" H- y# T! t6 k& w. [ ├─Project0 ? }' k+ y# Z$ X D% W w │ │ │ ├─inc7 [* F% {0 k7 g- e5 t4 B │ │ │ │ │ │ main.h │ │ │ hw_config.h │ │ │ fsmc_sram.h │ │ └ stm32f10x_conf.h │ │ │ ├─src6 e& I& W0 ~& S( T$ E0 S4 z% j │ │ │! z5 R5 Z: u2 o* u9 a( I ^ |# i │ │ │ iwdg.c │ │ │ rcc.c: |. F1 x; o2 O+ g# H- t' D │ │ │ gpio.c4 ?4 j1 h2 P0 d5 q) T. |1 \ │ │ │ nvic.c │ │ │ tim.c( e! c, i$ N# u1 L7 A- q8 { │ │ │ adc.c │ │ │ usart.c │ │ │ can.c5 s1 A* Q# L# T/ V8 y │ │ │ spi.c+ F: U, Z" a( C6 J$ |, e9 L% \ │ │ │ dma.c' ]: J5 I* G/ v0 R* J │ │ │ fsmc_sram.c! N4 y3 ?4 J/ C, I' l; _$ E │ │ │ hw_config.c │ │ │ stm32f10x_it.c! H" \% _7 c1 C, t* c │ │ │ main.c │ │ │ modbus.c5 I8 |" g, r5 N │ │ └ ymodem.c │ │ 7 ?+ |, E9 ^ m a) Y7 e │ └─MDK-ARM( c: `3 J/ O" u& N │ │ , P, @: p5 Z5 [# z2 E │ │ BootLoad_IAP.uvproj0 B$ _. ^4 T, E3 R │ │ FLASH_EXSRAM.sct /* Flash调试,分散加载文件 */$ J8 L+ E' K2 p5 O │ │ IRAM_EXSRAM.sct /* IRAM调试,分散加载文件 */ │ │ RAM.ini /* IRAM调试初始化文件 */ │ │ SIM_MAP.ini /* 软件仿真初始化文件 */ │ │ │ │ 3 U4 @' t6 X7 C' R* h │ ├─ROM /* Debug in Flash */ │ │ │ │ │ ├─rom_List │ │ │* U/ j) @7 p! e, {( k/ m( Q( B │ │ └─rom_out% a& E% j: d9 k: P3 f J │ │! R: z m, f2 \1 d# A6 { │ └─RAM /* Debug in Ram */: t; z+ q' @8 q- Y; y( ?9 G │ │ │ ├─ram_List4 W# {6 L( `4 ?& n5 h6 q1 ~ │ │ │ └─ram_out& z( R! e+ G$ u │ ├─Libraries/ C" q, q: k: O7 I+ ^ │ └─STM32F10x │ ├─CMSIS │ │ ├─Device │ │ │ └─ST │ │ │ └─STM32F10x │ │ │ ├─Include │ │ │ │ │ stm32f10x.h │ │ │ │ └ system_stm32f10x.h/ V4 y8 \0 ^& R" T4 C │ │ │ └─Source+ p% S# f% J, S6 I4 M- @) F │ │ │ └─Templates │ │ │ │ system_stm32f10x.c │ │ │ └─arm+ r& J6 m; B4 @* H( b; P4 q │ │ │ └ startup_stm32f10x_hd.s$ W' n$ Z" B' ~2 Z) } t* S │ │ └─Include, W9 l$ M# I4 `' n: S: l+ Z/ k │ │ └ core_cm3.h │ │ │ ├─STM32_USB-FS-Device_Driver$ {# ^$ i; j( b1 _6 G │ │ │ │ │ ├─src: a) k1 G( o0 `; L g9 S4 t% n │ │ │ │ usb_core.c │ │ │ │ usb_init.c/ z: L$ I; W) [8 d+ K$ {2 v0 F │ │ │ │ usb_int.c │ │ │ │ usb_mem.c4 o! I W4 G- \2 }7 T" F) v │ │ │ │ usb_regs.c │ │ │ └ usb_sil.c( j/ k' g8 Y0 n; L% @0 a7 U │ │ │ . m0 _# H* S7 t" y0 X/ F │ │ └─inc │ │ │ 9 c* q& T3 J$ q# E. F │ │ │ usb_core.h3 A. L1 N5 N9 ?) \ │ │ │ usb_def.h$ Q( T l5 _. X7 ^ r4 q2 J │ │ │ usb_init.h' ^$ j$ c1 S( \7 _6 k( N0 e" l9 Q8 q │ │ │ usb_int.h4 E. [( i$ ~( P/ j7 W7 ] │ │ │ usb_lib.h9 m5 q: \6 k- m9 b d. g. m │ │ │ usb_mem.h4 v6 f( C1 @* E7 H% G& f# m │ │ │ usb_regs.h │ │ │ usb_sil.h% e$ U' w8 I# f │ │ └ usb_type.h6 X% S& Z7 Z9 { │ │0 F- @4 p: Z u0 n- }4 C3 g+ Q │ └─STM32F10x_StdPeriph_Driver /* StdPeriph_Driver */4 L: ]2 u4 K2 L │ │ 4 F. ?& u0 G( |) \/ `- q2 N │ ├─src9 ^. x! z7 m1 U5 P' D8 D" U │ │ │ misc.c$ l* [; ]; v% b8 @5 e │ │ │ stm32f10x_adc.c+ g' g6 s+ Q2 r# G% h Z │ │ │ stm32f10x_bkp.c/ K3 g: [, }0 A' p6 n9 R │ │ │ stm32f10x_can.c │ │ │ stm32f10x_cec.c+ v0 Y: l, m6 Q' u │ │ │ stm32f10x_crc.c! c x' E: C* d7 N9 `% y t │ │ │ stm32f10x_dac.c2 J% k. J8 d8 s6 h │ │ │ stm32f10x_dbgmcu.c │ │ │ stm32f10x_dma.c │ │ │ stm32f10x_exti.c a1 s0 k" K8 B3 l; H │ │ │ stm32f10x_flash.c │ │ │ stm32f10x_fsmc.c │ │ │ stm32f10x_gpio.c# y& B# r+ h: @/ |. w/ V: g" i& {/ { │ │ │ stm32f10x_i2c.c0 [: r$ ?2 Y; Q │ │ │ stm32f10x_iwdg.c0 w8 ^# e! v Y' c │ │ │ stm32f10x_pwr.c │ │ │ stm32f10x_rcc.c |" O( }/ l3 f! Y3 }* N │ │ │ stm32f10x_rtc.c- B6 k( v9 M, b- n, U' f │ │ │ stm32f10x_sdio.c% g. r3 t' h2 _ │ │ │ stm32f10x_spi.c │ │ │ stm32f10x_tim.c │ │ │ stm32f10x_usart.c │ │ └ stm32f10x_wwdg.c │ └─inc │ │ misc.h2 o! T& c, V7 S7 M │ │ stm32f10x_adc.h │ │ stm32f10x_bkp.h) {) x4 [# R9 F2 w& f2 x$ ]5 m n │ │ stm32f10x_can.h# d8 \' a0 @) Q( G │ │ stm32f10x_cec.h │ │ stm32f10x_crc.h0 D' l: N8 t9 p/ P* l" O3 O* c │ │ stm32f10x_dac.h! d* N( j r4 s& i) x; y4 N8 k, G │ │ stm32f10x_dbgmcu.h │ │ stm32f10x_dma.h- O# V3 @) a- ^ \1 Z6 J │ │ stm32f10x_exti.h │ │ stm32f10x_flash.h │ │ stm32f10x_fsmc.h0 R% D5 S2 |& l* M& x │ │ stm32f10x_gpio.h3 F- r ]$ g. D7 x- x4 H: A │ │ stm32f10x_i2c.h │ │ stm32f10x_iwdg.h │ │ stm32f10x_pwr.h │ │ stm32f10x_rcc.h* F2 {5 k' {# y1 J: k │ │ stm32f10x_rtc.h8 `7 @$ O! C- W │ │ stm32f10x_sdio.h9 [7 S1 T- T, H% p │ │ stm32f10x_spi.h$ ? m( ~& P# p │ │ stm32f10x_tim.h# r. H* @1 r& f6 _9 A# e │ │ stm32f10x_usart.h │ └ stm32f10x_wwdg.h6 [/ q0 X3 g" w, W: z │: r/ |5 g5 t* M; M2 H' o │ └ BootLoad说明.txt - B; i, y3 S, h% E bootloader及256Kb的测试例程打包下载: |
基于STM32的自动跟踪小车
获取STM32代码运行时间的技巧
USB4 产品设计将会令 USB4 取得成功
小缓存实现大效果:X-NUCLEO-GFX01M1 和 TouchGFX 4.15让你的产品...
小缓存实现大效果:X-NUCLEO-GFX01M1 和 TouchGFX 4.15让你的产品...
STM32H7各产品应用定位
单片机是控制电子产品的大脑
为什么自己设计的嵌入式系统稳定性远不如工业级产品?
PCB之间的互连是产品EMC的最薄弱环节
嵌入式产品的开发过程中的各个阶段
RE:【原创】【MCU实战经验】+ 可在产品中使用的bootloader程序及测试例程打包上传。