最近研究ST芯片的内容ISP升级方法,按照官方推荐方式,需要设置BOOT引脚电平进入内容System Bootloader升级,感觉这种方式麻烦,所以查找是否可以软件方式直接跳转ISP进行升级;经过百度和各论坛查找资料,终于找到解决办法,并且经过验证大部分是可行的,少部分不行(暂时还没有搞清楚原因)- s6 {$ Z; z5 j- ~; S3 T" b 以下是软件跳转内容ISP的代码,可以直接调用即可: /**5 P. ^; u g% F2 _" [# J * Function to perform jump to system memory boot from user application q$ H8 ^# Z2 i# s7 _4 B *8 Y; s, E# B: m! P$ E * Call function when you want to jump to system memory */ void JumpToBootloader(void) { void (*SysMemBootJump)(void); /** * Step: Set system memory address. * * For STM32F429, system memory is on 0x1FFF 0000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */ //volatile uint32_t addr = 0x1FFF0000; /** * Step: Set system memory address. % i- [3 |' X5 s1 ^; f ` * * For STM32F103, system memory is on 0x1FFF F0005 F% }; w, U6 b: S * For other families, check AN2606 document table 110 with descriptions of memory addresses */3 F! C5 |& f3 ], S3 {. f //volatile uint32_t addr = 0x1FFFF000;7 y" R3 e7 j' b; F( y2 ~/ K /** * Step: Set system memory address. % Q- ]8 M# {9 W. x * , N: Z* o9 f9 R+ ^! Q * For STM32F107, system memory is on 0x1FFF B0001 T1 V! x7 }" J * For other families, check AN2606 document table 110 with descriptions of memory addresses */# z5 h+ ^+ _. S2 q+ i //volatile uint32_t addr = 0x1FFFB000;: L3 X" ^, F6 @) w. p /**8 b( T& ?; ~ c' h5 N. ~ * Step: Set system memory address. ' V% v$ N4 f$ k" P* X ] b) W * 9 w- o6 n+ Y7 t Y$ B& O% `5 i * For STM32F303, system memory is on 0x1FFF D800 * For other families, check AN2606 document table 110 with descriptions of memory addresses 3 h5 W) p/ ?! \% m9 f$ V) y$ [ */ //volatile uint32_t addr = 0x1FFFD800; /** * Step: Set system memory address. ' K# c( R' p# p * : ]& i4 e ^+ ] * For STM32L073, system memory is on 0x1FF0 0000# K) s% B& ~4 q* t, K- j$ ^7 s * For other families, check AN2606 document table 110 with descriptions of memory addresses 5 l" g" h2 d0 l9 U N# I */5 k, D2 t% R; _6 `$ K volatile uint32_t addr = 0x1FF00000;9 x) D/ S4 J* x f& X" K0 h5 I K /**" b9 u0 G# F4 ?3 R' i! q, S& N * Step: Disable RCC, set it to default (after reset) settings * Internal clock, no PLL, etc. */6 f2 Z* N+ ?* ~1 r, K #if defined(USE_HAL_DRIVER)! J0 O$ N, m& Q) u& I3 i HAL_RCC_DeInit();5 a2 u" C/ ^& v #endif /* defined(USE_HAL_DRIVER) */# u E' `; c, i. | #if defined(USE_FULL_LL_DRIVER)8 d. ~* m/ d2 Z" p LL_RCC_DeInit(); #endif8 [; ]( o3 D' A0 |3 f: e+ Z# _ #if defined(USE_STDPERIPH_DRIVER) RCC_DeInit(); #endif /* defined(USE_STDPERIPH_DRIVER) */ /** * Step: Disable systick timer and reset it to default values! L1 n, S/ E' [# h- [ */ d4 Q0 W$ i1 J7 x$ n SysTick->CTRL = 0;$ O/ z1 c/ v1 W" {$ v. O& S/ R7 S; K O SysTick->LOAD = 0; SysTick->VAL = 0; /** * Step: Disable all interrupts */2 R3 U, j" L$ U+ A6 o% [" g1 R1 ` __disable_irq();0 L0 V8 V) [0 ^6 ~3 D: ~ /**& X# s {8 C. x a * Step: Remap system memory to address 0x0000 0000 in address space+ s6 ]4 i. \ i" ^. }) } * For each family registers may be different. * Check reference manual for each family. *; L0 V& h# i& p1 H- b% z/ H h * For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0]) * For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0]) * For others, check family reference manual */+ Y \3 D) V. R# ]* ^5 F6 Y) k //Remap by hand... {9 ~4 q. P" k$ x# V# Y* | #if defined(STM32F4) SYSCFG->MEMRMP = 0x01;! c2 j* L( L1 }3 S8 {: D2 Q5 d #endif #if defined(STM32L0) SYSCFG->CFGR1 = 0x01;, \/ E" c/ v2 Z- G #endif #if defined(STM32F0)) l1 j9 X* R# L SYSCFG->CFGR1 = 0x01;% }, ]3 S* e6 R$ | #endif5 Z: J7 Q2 T: y# x% S. H //} ...or if you use HAL drivers! E( F+ y6 _9 g# ?, J9 V& v8 W; c //__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you 2 b% m+ \. b+ a9 l, V8 Q# j /** * 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))); /**6 { Q2 Q- r( Q8 Z * Step: Set main stack pointer.% z2 p, |% X: B/ Q1 ^ * This step must be done last otherwise local variables in this function0 Q6 y r5 R1 j8 Z5 h$ u8 f * don't have proper value since stack pointer is located on different position * * Set direct address location which specifies stack pointer in SRAM location *// X) s' ?* A* }7 q: G __set_MSP(*(uint32_t *)addr); /** * Step: Actually call our function to jump to set location, F; G: W" q; i8 E$ s# e * This will start system memory execution+ i$ M8 D) H2 j) Q/ U- _$ H8 [ */ SysMemBootJump();% e/ z* x) Y5 b# _$ W2 y , c4 p( p' t* ]5 ^4 E$ d /**: o6 [0 C6 w8 t6 { * Step: Connect USB<->UART converter to dedicated USART pins and test- a+ Q. W5 ]3 l7 u* o * and test with bootloader works with STM32 Flash Loader Demonstrator software */" ~9 s+ n- k/ g. V }. b9 k0 s0 D( q* }) ` 然后介绍下测试结果: 1、F0系列:STM32F030、STM32F051、STM32F070、STM32F071和STM32F072芯片,其中除STM32F070跳转运行ISP运行错误(发现内部ISP代码好像有问题,具体也不确定)外,均可以支持软件跳转ISP后串口方式升级; 2、F1系列:STM32F103和STM32F107芯片,均可以支持软件跳转ISP后串口方式升级; 3、F2系列:无芯片平台验证; 4、F4系列:STM32F407芯片,支持软件跳转ISP后串口方式升级;1 ^* P8 I* u* J% q: p 5、L0系列:STM32L073芯片,支持软件跳转ISP后串口方式升级; 6、L4系列:STM32L4R5芯片,软件跳转ISP后运行直接跳转Hardfault(后续查找原因);0 E0 ]5 n2 n% b1 P+ | S; j2 C 7、其它系列均无平台验证; |
基于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