最近研究ST芯片的内容ISP升级方法,按照官方推荐方式,需要设置BOOT引脚电平进入内容System Bootloader升级,感觉这种方式麻烦,所以查找是否可以软件方式直接跳转ISP进行升级;经过百度和各论坛查找资料,终于找到解决办法,并且经过验证大部分是可行的,少部分不行(暂时还没有搞清楚原因) 以下是软件跳转内容ISP的代码,可以直接调用即可: /** * Function to perform jump to system memory boot from user application8 |) y1 E0 |( g( `9 D6 f" Q *$ Q1 N. M6 E( t- L9 e2 m$ W# } * Call function when you want to jump to system memory9 g' ]1 I, z* i* S& S" G, O */6 s% W+ ?+ q8 \6 o# M! w void JumpToBootloader(void) { void (*SysMemBootJump)(void); 0 J- u3 N: Y* L9 L5 S3 ? /**; b8 @7 B; Z6 O. v * Step: Set system memory address. % i5 j+ C1 ^" L# Q4 D4 {( ? * 5 S3 E$ I# r7 M * For STM32F429, system memory is on 0x1FFF 0000 * For other families, check AN2606 document table 110 with descriptions of memory addresses ! \3 o# A$ z8 X# b1 M */ //volatile uint32_t addr = 0x1FFF0000;! G- d7 w6 L1 z9 c" E" F* [ /*** P+ T# E) X* q. V A * Step: Set system memory address. 4 T) r+ ~# [* c& ]" U7 u * 8 C& B1 i& L1 K. J, A; |8 { * For STM32F103, system memory is on 0x1FFF F000# g0 [7 @& u" a! O' P; X * For other families, check AN2606 document table 110 with descriptions of memory addresses */, q! @2 t1 r! D9 E //volatile uint32_t addr = 0x1FFFF000;6 \; N- u3 a4 a' R /** * Step: Set system memory address. k- @4 q$ j: P * * b5 y. w. _1 ^/ T * For STM32F107, system memory is on 0x1FFF B000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */8 V2 J# {. f: {! T //volatile uint32_t addr = 0x1FFFB000; /** * Step: Set system memory address. * # z5 E$ J& x- A) f3 d * For STM32F303, system memory is on 0x1FFF D800 * For other families, check AN2606 document table 110 with descriptions of memory addresses */: {; @3 @' h% {' X //volatile uint32_t addr = 0x1FFFD800;( h) d& p1 J) v8 d3 f6 j& y- m /*** k: K% r2 L% W * Step: Set system memory address. * 7 z9 x# k$ _& O! l * For STM32L073, system memory is on 0x1FF0 0000 * For other families, check AN2606 document table 110 with descriptions of memory addresses */0 q9 h9 C1 n+ ^* e- K [% v volatile uint32_t addr = 0x1FF00000; /**4 v$ Y0 k2 x# x3 J% Q+ i0 u * Step: Disable RCC, set it to default (after reset) settings * Internal clock, no PLL, etc.+ b# ~/ N$ ~* j. u4 ~% } */ #if defined(USE_HAL_DRIVER) HAL_RCC_DeInit(); #endif /* defined(USE_HAL_DRIVER) */9 v- }0 h1 L- M6 @ #if defined(USE_FULL_LL_DRIVER) LL_RCC_DeInit();/ F, h- \# W* K #endif5 ~0 C7 ]) _$ @! y9 t Y3 s #if defined(USE_STDPERIPH_DRIVER)# W8 @3 `, Q6 N1 A$ w+ s( x RCC_DeInit(); #endif /* defined(USE_STDPERIPH_DRIVER) */- S: z6 H0 d* p b5 l$ g! } & P! p+ j, `: F7 w /**. @/ Z/ t$ l' c T) T# k+ H * Step: Disable systick timer and reset it to default values */ SysTick->CTRL = 0;8 T: t3 E1 l, a( G$ i SysTick->LOAD = 0; SysTick->VAL = 0; /** * Step: Disable all interrupts4 j; L) \; M7 {4 p5 _$ c */ __disable_irq(); * I( Z1 [3 J+ Z, \3 E3 w /** * Step: Remap system memory to address 0x0000 0000 in address space * For each family registers may be different. $ e7 G/ g4 x- m: l * Check reference manual for each family.2 ~5 g. [$ p1 W+ U7 k2 ? * * For STM32F4xx, MEMRMP register in SYSCFG is used (bits[1:0])# u Q8 y ?1 Q# W6 f$ ~ * For STM32F0xx, CFGR1 register in SYSCFG is used (bits[1:0]) * For others, check family reference manual */ //Remap by hand... {3 a# f1 o7 `, e4 {, i2 M4 Z3 _8 [; J #if defined(STM32F4)8 j8 t6 |( \2 u3 L/ Q$ V$ ^( L5 j SYSCFG->MEMRMP = 0x01; #endif8 ^1 k+ |' P+ C- I* d& C #if defined(STM32L0) SYSCFG->CFGR1 = 0x01; #endif #if defined(STM32F0)" [8 j8 N+ z) @( Y SYSCFG->CFGR1 = 0x01;8 O1 J9 }" f; r4 C6 ] #endif( P+ b' n! p5 a //} ...or if you use HAL drivers& A! U3 U, r% {2 L# L- \, C //__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you ( B" c) k; ~8 I2 o1 t* ` /**0 ^9 z6 d" i; }! {8 }8 L6 H * Step: Set jump memory location for system memory * Use address with 4 bytes offset which specifies jump location where program starts */+ [& X( J0 Y2 ] j2 F. Y SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));7 g. }: ]* j% ~, f t& p* R9 C /** * Step: Set main stack pointer.9 n& j2 T6 w, N S * 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% i A1 c8 r- e0 O9 G! e * * Set direct address location which specifies stack pointer in SRAM location */8 b5 ^: {8 v6 v& i& r6 f! \2 ?$ c __set_MSP(*(uint32_t *)addr); /**" s: L: D8 ~ L) p1 K L- G * Step: Actually call our function to jump to set location& S" Q/ H' q1 l * This will start system memory execution */. _. l. K/ J) I SysMemBootJump(); /** * Step: Connect USB<->UART converter to dedicated USART pins and test * and test with bootloader works with STM32 Flash Loader Demonstrator software9 T4 Z* M* c. m/ y" o */ } 然后介绍下测试结果:5 J( Q: |: q: q& R- g- w. D 1、F0系列:STM32F030、STM32F051、STM32F070、STM32F071和STM32F072芯片,其中除STM32F070跳转运行ISP运行错误(发现内部ISP代码好像有问题,具体也不确定)外,均可以支持软件跳转ISP后串口方式升级; X F5 T! [* E" }/ d: N( C$ K 2、F1系列:STM32F103和STM32F107芯片,均可以支持软件跳转ISP后串口方式升级; 3、F2系列:无芯片平台验证;* w; L& E6 |4 l; J6 N( x 4、F4系列:STM32F407芯片,支持软件跳转ISP后串口方式升级;; G6 ^0 i4 B( M4 G! ? 5、L0系列:STM32L073芯片,支持软件跳转ISP后串口方式升级; 6、L4系列:STM32L4R5芯片,软件跳转ISP后运行直接跳转Hardfault(后续查找原因);4 X2 v& p7 {; Y: a- C7 v 7、其它系列均无平台验证;2 q2 g' ?8 ]$ O# _ |
基于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