最近研究ST芯片的内容ISP升级方法,按照官方推荐方式,需要设置BOOT引脚电平进入内容System Bootloader升级,感觉这种方式麻烦,所以查找是否可以软件方式直接跳转ISP进行升级;经过百度和各论坛查找资料,终于找到解决办法,并且经过验证大部分是可行的,少部分不行(暂时还没有搞清楚原因); w) @- ^3 v; n 以下是软件跳转内容ISP的代码,可以直接调用即可:* o1 S0 G9 ^- w$ k% G /**9 K1 Q2 O8 E' N3 U2 y. o8 Q * Function to perform jump to system memory boot from user application * * Call function when you want to jump to system memory */ void JumpToBootloader(void) { void (*SysMemBootJump)(void); /** * Step: Set system memory address. * 1 l% g4 S' F P1 h * For STM32F429, system memory is on 0x1FFF 0000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */3 S0 ?4 ?- y8 o& ]1 q9 S //volatile uint32_t addr = 0x1FFF0000; /** * Step: Set system memory address. * * For STM32F103, system memory is on 0x1FFF F000/ j( L* [8 N+ }* t5 U * For other families, check AN2606 document table 110 with descriptions of memory addresses 4 ?* t0 `# z# i7 t( ]- I& v0 a */ //volatile uint32_t addr = 0x1FFFF000; /** |+ o) |% b6 F2 ~0 L * Step: Set system memory address. * 1 X% z( [" q8 u * For STM32F107, system memory is on 0x1FFF B000- F! M/ [ o6 R$ v7 c * For other families, check AN2606 document table 110 with descriptions of memory addresses : ^7 u9 P `. t) f2 z, { *// B& H% [' |# z1 U/ W //volatile uint32_t addr = 0x1FFFB000;, y2 B$ n3 [# Y% M! ?9 ]7 p /**- d/ }3 Q i7 P * Step: Set system memory address. 5 ^6 v# I5 @) V0 a5 } f/ N * & M1 m. f2 i4 L$ p * For STM32F303, system memory is on 0x1FFF D800 * For other families, check AN2606 document table 110 with descriptions of memory addresses */9 Z& D0 n' _* O- M, v2 d //volatile uint32_t addr = 0x1FFFD800;2 W! n% k7 B- O$ l7 ]4 O /** * Step: Set system memory address. * ) }. |- N8 A3 {) P/ P3 u * For STM32L073, system memory is on 0x1FF0 0000( i( {$ S" l" Z* X * For other families, check AN2606 document table 110 with descriptions of memory addresses */ volatile uint32_t addr = 0x1FF00000;' k0 e: j0 [* q5 n # c( w8 L3 B: C2 ]' Z; V0 x /**9 L, U% d7 Z6 ~3 }, f: g Q+ q1 O * Step: Disable RCC, set it to default (after reset) settings * Internal clock, no PLL, etc.3 W3 d; K2 w8 ]& r- q/ n */ #if defined(USE_HAL_DRIVER)/ v/ M, I8 J9 K. Z! M HAL_RCC_DeInit();* W+ @ z4 G: S+ p4 A8 m# C #endif /* defined(USE_HAL_DRIVER) */ #if defined(USE_FULL_LL_DRIVER) LL_RCC_DeInit();( ^, z4 B" x! h/ |& n9 g: v( \ #endif #if defined(USE_STDPERIPH_DRIVER) RCC_DeInit(); #endif /* defined(USE_STDPERIPH_DRIVER) */- o. O; p! B0 S1 I0 ? 9 ~6 R# I& E" q. b /** * Step: Disable systick timer and reset it to default values/ z% l- k8 V# i */ SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; /** * Step: Disable all interrupts */3 f" I$ @+ q: N1 @6 P9 \) { __disable_irq();, G, k7 u# s0 [ - m. _; g6 ~6 {6 l# x /** * Step: Remap system memory to address 0x0000 0000 in address space+ L1 i" W7 I2 I. z& ]* n * For each family registers may be different. * Check reference manual for each family.8 @3 \. b9 y0 B& @3 h" {5 X5 v *0 H3 n; t! [; `" p9 ] * For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0]) * For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0])+ X0 w! @, m$ g, _% O' ^, ]6 k2 O * For others, check family reference manual' p: Q+ A, I- Q */" J/ Q; m% ?1 P* `6 k# ]2 k& L //Remap by hand... {& W: y. u2 f i$ C6 {: L- B$ e0 Z #if defined(STM32F4)% r9 M) ]/ N& U- [% g" W4 g SYSCFG->MEMRMP = 0x01;- ]; b7 r, p# a0 y& z #endif! o+ I2 l3 D! \9 @ #if defined(STM32L0) SYSCFG->CFGR1 = 0x01;- e4 g) {2 E1 h) Z #endif #if defined(STM32F0) x- ]! b8 i0 M6 x9 k) c9 j0 b, d SYSCFG->CFGR1 = 0x01; #endif //} ...or if you use HAL drivers //__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you# O- f* c4 k5 @6 l /**4 ?& n2 y, Y( D. X) ]8 @* ] * Step: Set jump memory location for system memory * Use address with 4 bytes offset which specifies jump location where program starts */ SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); /**: U6 I& l( w& [! @9 F8 ^$ o- k; [9 F! K * Step: Set main stack pointer./ n+ q, u/ p# V/ N R& Z6 H, P * This step must be done last otherwise local variables in this function# p% b- m: c$ v1 @3 l * don't have proper value since stack pointer is located on different position * * Set direct address location which specifies stack pointer in SRAM location! n$ W' p2 d) A& { |1 u */ __set_MSP(*(uint32_t *)addr); /** * Step: Actually call our function to jump to set location3 @* R! J# M1 u* B y* m f8 @ * This will start system memory execution- ~- a( _3 b2 R1 q */ SysMemBootJump(); 5 k4 e% u+ ]$ k4 V8 |/ J! W% w' z /** * Step: Connect USB<->UART converter to dedicated USART pins and test9 B% n+ W$ D5 x" U R- h * and test with bootloader works with STM32 Flash Loader Demonstrator software4 h1 p& |0 l$ p4 y0 P. @ T */ }2 r% X) T% J# I6 I 然后介绍下测试结果: 1、F0系列:STM32F030、STM32F051、STM32F070、STM32F071和STM32F072芯片,其中除STM32F070跳转运行ISP运行错误(发现内部ISP代码好像有问题,具体也不确定)外,均可以支持软件跳转ISP后串口方式升级;, U! g5 E# V$ u) O/ O( H% d1 Z0 n8 w 2、F1系列:STM32F103和STM32F107芯片,均可以支持软件跳转ISP后串口方式升级; 3、F2系列:无芯片平台验证; 4、F4系列:STM32F407芯片,支持软件跳转ISP后串口方式升级; 5、L0系列:STM32L073芯片,支持软件跳转ISP后串口方式升级; 6、L4系列:STM32L4R5芯片,软件跳转ISP后运行直接跳转Hardfault(后续查找原因);& ?- ]3 s- J& @ 7、其它系列均无平台验证;" R+ }0 W1 `; J9 p) s2 I * y/ P, M4 U0 m+ Q+ T/ |+ {" M . |0 g3 x' K% U. ~* U3 [( X- H |
基于STM32L476+64M QSPI接口PSRAM(IPS6404L)开源分享(含源码)
基于STM32L4R9 的QuadSPI Flash 通讯速率不理想经验分享
STM32L4超低功耗功能概述
基于STM32L431RC Standby和RTC中断唤醒经验分享
基于STM32L431的睡眠模式经验分享
STM32L4R9 的 QuadSPI Flash 通讯速率不理想
STM32L4、STM32L4+和STM32G4系列 微控制器上的专利代码读取保护
STM32L433在STOP模式USART不能工作的解决办法
【实测教程】基于STM32L4系列的实测教程分享合集
STM32L4系列MCU的五种振荡器和使用说明
我用的开发板是官方的nucleo开发板,连接串口用的是lpuart1