|
最近研究ST芯片的内容ISP升级方法,按照官方推荐方式,需要设置BOOT引脚电平进入内容System Bootloader升级,感觉这种方式麻烦,所以查找是否可以软件方式直接跳转ISP进行升级;经过百度和各论坛查找资料,终于找到解决办法,并且经过验证大部分是可行的,少部分不行(暂时还没有搞清楚原因) 以下是软件跳转内容ISP的代码,可以直接调用即可:5 o* E5 n8 g" R6 x9 g+ J /**( H v/ Z5 B$ {* W6 J * Function to perform jump to system memory boot from user application; [" U! |7 @- F+ d7 M- l8 q *& g6 H4 F$ u; J1 X+ P * Call function when you want to jump to system memory& J. i3 b3 O0 Y9 L* B0 N */ void JumpToBootloader(void) {2 k& @! C: E& y0 ]3 t& P void (*SysMemBootJump)(void); /**- s2 ? i* q2 [: @7 R) a; o * Step: Set system memory address. * % N0 d* V6 c6 U) h6 h0 N * For STM32F429, system memory is on 0x1FFF 0000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */* s0 ?# A0 L! M( X% l0 S2 w //volatile uint32_t addr = 0x1FFF0000;( m3 W% O1 E/ P. k; g /**: ?7 q& @! m9 E# @6 @0 } * Step: Set system memory address. ) g$ u8 S, @# a" l, g& B0 I * , n( h# G: d# T `$ t, I( g * For STM32F103, system memory is on 0x1FFF F000; n$ U9 g/ f7 l; P * For other families, check AN2606 document table 110 with descriptions of memory addresses 4 c1 {, u( h% a% |' f */ //volatile uint32_t addr = 0x1FFFF000; /**9 A; y/ u( ^! v& k * Step: Set system memory address. * * For STM32F107, system memory is on 0x1FFF B000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */# P. {6 y+ L$ v: U //volatile uint32_t addr = 0x1FFFB000; /** * Step: Set system memory address. * 5 e7 c e, L/ a' a * For STM32F303, system memory is on 0x1FFF D800 * For other families, check AN2606 document table 110 with descriptions of memory addresses 6 {: s4 D# D( b# @* F k */9 T& ~0 d! f. g9 t# ~ //volatile uint32_t addr = 0x1FFFD800; /**2 {! k+ _: e% C% G * Step: Set system memory address. & R9 a. |. ^3 n$ v * * For STM32L073, system memory is on 0x1FF0 0000" E1 {: R3 B1 I * For other families, check AN2606 document table 110 with descriptions of memory addresses * J( ?; @- T% }5 O( g: b* l6 H */7 m8 O8 [4 W, } volatile uint32_t addr = 0x1FF00000; 3 r7 n1 f3 }$ Y) I /** * Step: Disable RCC, set it to default (after reset) settings+ j, Y4 H1 l9 w7 l * Internal clock, no PLL, etc.7 o) Q0 u9 |) `. S O2 a */% y7 l3 [8 |4 v4 T! w #if defined(USE_HAL_DRIVER)8 b$ Y' q4 l C# {! ^ HAL_RCC_DeInit();( c' X1 ]7 _" E+ J& g #endif /* defined(USE_HAL_DRIVER) */' }3 [) G/ k* V1 {+ B2 s5 R5 u+ Z #if defined(USE_FULL_LL_DRIVER)0 j- q; B2 C) H1 f& m LL_RCC_DeInit();% x1 f8 {* ]' c0 P. A; N& v #endif1 V4 V' c' z! k! }' M #if defined(USE_STDPERIPH_DRIVER) RCC_DeInit();5 ? K) U4 D1 Q; w, f% h% o: S& } #endif /* defined(USE_STDPERIPH_DRIVER) */ ( f5 Q; Y" O t+ a /** * Step: Disable systick timer and reset it to default values0 _/ P" k7 g' }! n( @/ }. }& Y. V0 h/ ` */ SysTick->CTRL = 0; SysTick->LOAD = 0;- V9 z0 J4 N. A6 e, u9 `3 {4 K SysTick->VAL = 0;8 D" O7 C( K4 J4 R* Z q2 r% | ! U; s; U( p- c& S8 x /**0 ~. i: H) n, y * Step: Disable all interrupts9 y- J' b. C* t */: o3 c4 I, D& h) Y' t& ]1 U __disable_irq();5 f# z# j9 J/ }+ \+ O /**4 f! @5 m; X* F! R- ?% N& _1 B * Step: Remap system memory to address 0x0000 0000 in address space * For each family registers may be different. 6 L; R1 K! g6 U8 S# q8 B * Check reference manual for each family.) Q) q( \& x/ E *7 q. x, n* V' X, l * For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0]), ^ c5 }& ?+ f! b' u1 c; ~ * For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0])- C8 j( x! W( M K9 Q, @ * For others, check family reference manual$ m$ o+ _, R' X$ z, o */ //Remap by hand... { #if defined(STM32F4) SYSCFG->MEMRMP = 0x01;# i9 \# ^: }4 ] #endif( V8 k3 A# `1 f i #if defined(STM32L0) SYSCFG->CFGR1 = 0x01;) Y0 v% p d$ v! x* o% y& ? #endif #if defined(STM32F0) SYSCFG->CFGR1 = 0x01; #endif6 j% B& _. r4 T9 e3 C; D) A5 }% ?; z //} ...or if you use HAL drivers( `0 x8 P& ?+ z1 `2 H$ N //__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you / ~+ L' c, ?( k( N4 C /** * Step: Set jump memory location for system memory * Use address with 4 bytes offset which specifies jump location where program starts */# U5 d4 |% u2 W) ]: Q8 ^, |7 s SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); , o* R: H9 D( s /**0 _, G4 ^6 [" a * Step: Set main stack pointer. * This step must be done last otherwise local variables in this function * don't have proper value since stack pointer is located on different position" `# U9 Y8 _7 @5 H4 H! n *. i6 t2 S5 Y; ~5 I * Set direct address location which specifies stack pointer in SRAM location */4 J3 n) ?7 @+ p; r2 c/ Z% s; f* p __set_MSP(*(uint32_t *)addr); + c9 a1 f/ B0 r! H1 _/ r! R /** * Step: Actually call our function to jump to set location5 o' }, h& j1 i) G" G+ D7 U$ p * This will start system memory execution */; T/ c% Q# N* d0 Q- d# U SysMemBootJump();+ O1 H$ p/ \" Q; P; M7 z$ N q 1 w! j. x L, f /** * Step: Connect USB<->UART converter to dedicated USART pins and test: i1 Y* U7 B" p& Q * and test with bootloader works with STM32 Flash Loader Demonstrator software Y6 z. q; M) d/ K */9 o2 s: l1 f! X7 R& m" U } A( [. a& s# a: z 然后介绍下测试结果: 1、F0系列:STM32F030、STM32F051、STM32F070、STM32F071和STM32F072芯片,其中除STM32F070跳转运行ISP运行错误(发现内部ISP代码好像有问题,具体也不确定)外,均可以支持软件跳转ISP后串口方式升级; 2、F1系列:STM32F103和STM32F107芯片,均可以支持软件跳转ISP后串口方式升级;& ~8 z5 x! D7 b( s/ |) X, c 3、F2系列:无芯片平台验证;' w; j+ m/ j2 t# Q' K7 j 4、F4系列:STM32F407芯片,支持软件跳转ISP后串口方式升级; m1 V) W6 T0 I* Q$ j% U 5、L0系列:STM32L073芯片,支持软件跳转ISP后串口方式升级;" G, H/ _/ U# b' Z; \ 6、L4系列:STM32L4R5芯片,软件跳转ISP后运行直接跳转Hardfault(后续查找原因);, [6 ^! e. S/ F 7、其它系列均无平台验证; % C" Z$ c% [$ V6 f7 r / V2 _, n* }4 J* J. C. a6 q. w |
STM32L4R9 QuadSPI Flash通讯速率优化解析 32位总线的DMA传输适配核心方案
【STEVAL-STWINKT1B评测】运行Datalog固件并记录运行时间
【STEVAL-STWINKT1B评测】数字麦/模拟麦对比测试+音频配套上位机软件开发
【板卡评测】STEVAL-STWINKT1B读取 ACC/GYRO/MAG 实时数据
小白也能明白的STM32的低功耗与唤醒机制
【STM32入门学习路径指南】(四步走)
STM32和Arduino对比,谁更耐打?
STM32系统中2种数据掉电保护的方法
STM32 LL为什么比HAL高效?
STM32小白入门指南:从基础到OTA实现方案
微信公众号
手机版
我用的开发板是官方的nucleo开发板,连接串口用的是lpuart1