例程说明* a: D6 \" c6 X' @3 X( ^
STM32G0xx在对Flash操作时,有时会出现HardFault异常、或者出现擦除、写入失败的情况,故有此记录。1 g" P, N7 J" |( n5 q
STM32G0xx LL库官方没有提供Flash相关的操作需要自己写,可借鉴HAL库。
1 B5 f; D* |' P% Q. s( V$ _& c# u6 M% U. a! I9 ]4 z
宏定义说明6 ~7 C7 j* @$ d& _9 L( q$ C
2 J3 s6 y W) M C9 g! K- #define XMEM_ALIGN_SIZE(size , align) (((size) + (align) - 1) / (align))
' w$ Z9 E# O B! {1 l
8 g3 n$ F* W( C) ~- C- /* 获取成员m在结构体t中的偏移位置 */
- Q' C w# l; i( \4 F( ` - #define XOFS(t , m) ((u32)(&(((t *)0)->m)))
; C, ~5 I: b o# q0 F
# B0 h( ^- B, C9 R' C) f" c) x- #define SYSTEM_ARG_STORE_START_ADDRE (0x0800F800UL)
" M: V7 v& `$ x ^) u3 R
8 R2 `; b j8 O- {# i, V- #define FLASH_OPT_OVERTIMER (0x1FFFF)
+ k% i5 a+ A8 e6 U - #define FLASH_OPT_TRY_COUNT (5)
复制代码 ' s3 S; ~$ u1 W+ e
Flash解锁与加锁
/ T% _ r) F/ ?; z$ u* a6 g- {- /* Unlock the FLASH control register access */
" n1 \5 P* R5 o( @ - static u8 ubFLASH_Unlock(void)1 h' _/ z$ I5 f4 O
- {# f" ^: K7 `. u0 P) R# P" }
- u8 sta = 0;9 t' X: j0 W3 |- R& Y5 y* T
- # X5 |, u: Z' B1 \4 O! x$ _
- if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)$ u, D$ ^ w* i+ y# A
- {* ]0 V5 z0 |2 Y5 ~, L
- /* Authorize the FLASH Registers access */
( c" J; ^! D `9 u - WRITE_REG(FLASH->KEYR, FLASH_KEY1);4 g) {* S6 Q) d0 a& m
- WRITE_REG(FLASH->KEYR, FLASH_KEY2);* D) \* j2 D4 \% ]
- 9 O4 U& Z- b+ ~, X3 W" O
- /* verify Flash is unlock */
0 i& K: Y d M9 d - if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)3 o0 s# m* V" M! k* u8 a
- {
0 r3 B: u. I1 H& V: j( [ - sta = 1;, N% z* r+ `! r e- O3 L3 |5 q7 r" w
- }
" c% H% G& c) b, N/ c; r& o9 O - }4 S$ a/ h- g, c0 d. ~
$ S& k: {# W+ h2 b- return sta;
F1 v* [, P# V4 @- O: o" E7 ` - }5 \6 S* U! ^) g% W6 Q
- " ?: f! [4 L7 x) V7 B
- 8 h2 Y# t) R3 j: g, d4 ?3 J% Q
- /* Lock the FLASH control register access */4 S! e/ Y" T5 N. W/ F/ {# i
- static u8 ubFLASH_Lock(void)
( Y; y! J' H- `, m& { - {
0 k* C: D* j0 r. [ f2 }" s - u8 sta = 1;& w- P% k4 T4 A1 }1 S
- 8 D' j/ ^6 J! s
- /* Set the LOCK Bit to lock the FLASH Registers access */! l4 n) Z' `% Z( `
- SET_BIT(FLASH->CR, FLASH_CR_LOCK);4 R% W4 [+ |% S: c
- 9 i+ C, ?. M0 o5 [5 e
- /* verify Flash is locked */$ a: D. a' `4 Z$ s5 U: e: @
- if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)* }5 q! _ M; L0 K+ e5 B+ }
- {# R- `0 _2 z# ^; m
- sta = 0;, f7 U/ ^$ ?) J' h9 v: G
- }" q0 c! h; f# r2 @3 T1 n, H$ y) c
- 2 X$ `: c$ j2 N1 s, N0 k
- return sta;8 s# U8 E% B1 v2 }
- }
复制代码 3 m- g9 M9 ]. Y( O
Flash选项字节解锁与加锁7 w0 x8 R/ @2 B% e2 m$ d
- /* Unlock the FLASH Option Bytes Registers access */6 `* I6 j2 E( w8 ]6 p/ r1 m
- static u8 ubFLASH_OB_Unlock(void)7 `0 d% ]4 O9 \+ E" Z$ R
- {" o( ^0 R0 N$ a7 a
- u8 sta = 1;
8 H/ G! f, t/ t: a T/ H
& T8 r! w: W0 q8 _, `% w- if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00U)
7 |# ?' R# e+ t4 \ - {
% f: s9 P0 S* I! k( A: W2 z - /* Authorizes the Option Byte register programming */7 w* a$ w) k5 S& y( G+ l
- WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);: a8 ?, ?8 i" c& g# `2 c
- WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);5 o. \2 V1 u1 u' M9 c' ^4 k- x
6 u! R9 P# K! |, p) ?% X- y9 E2 ^- /* verify option bytes are unlocked */" D0 c9 i0 s' r( e# U/ l) b* s* e
- if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0x00U). C: z. j+ e6 f, |! o- R
- {3 }$ N: |( ^5 a, v- C9 Z
- sta = 0;
% ?0 A1 t7 ^* @# T( y - }* Q7 @: e; b# ~9 i. j- \0 s8 E# J+ N# {4 D
- }9 _; s2 S5 l) u* s; y- ]$ m
3 h4 g, [) B/ d4 U9 Y6 V- return sta;, h" r! x0 F, {8 B" @
- }
0 n: @0 X9 _1 a1 X
; X7 K$ o+ S+ K4 P9 r- & F, Y/ m0 w7 o3 S" w
- /* Lock the FLASH Option Bytes Registers access */
. b7 V# E2 E& \ - static u8 ubFLASH_OB_Lock(void)
0 h; L& j. n( R" ?6 d3 D - {3 w$ P6 ~6 |* }5 H
- u8 sta = 1;' e3 _/ j. r. t6 a3 S
- , B/ S+ r' \& O. Y
- /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */$ h6 Q! Y! m: p6 [5 f5 u, n
- SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);4 r$ d! ]( z+ r* Z/ j
- 0 I4 {( \8 i8 W2 z/ l
- /* verify option bytes are locked */
) S- i. u* B( p9 G - if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)+ s P+ e, K3 S! M. \8 L2 R; X
- {$ T4 E7 W. p$ l8 w7 ?
- sta = 0;
; y" t* D0 e, a6 z' H1 R3 A7 e - }( U. O. J8 \# _6 m! d, T
! J: ?' j& _9 U! B" m- return sta;
3 a4 @# H3 s9 k7 F. R5 o - }
复制代码
- m! ~. I' R8 |/ T9 ]- gFlash擦除页' B4 v' c! k' y2 d& c
- /* Gets the page of a given address */
: ~1 s+ F! b; w# @+ A! }" a9 X! v - static u32 ulGetPage(u32 startAddr)
1 K \1 V: C7 l Q, \$ H! ?1 z& R( h# G - {. ]: A* p3 h- r. J# z, `1 _
- return ((startAddr - FLASH_BASE) / FLASH_PAGE_SIZE);1 N9 _0 x( M1 o
- }
7 t6 h% M) `# O
. S4 n' b) ^$ X, F- 4 F/ g5 ~ @0 z9 S3 i8 e
- /* Erase the specified FLASH memory page */) h. g0 g1 u' K. S0 c2 ?- y6 ^
- static u8 ubFLASH_PageErase(u32 page)
1 _2 Y3 _9 `( V" o - {
( S" f: C0 y) x - u32 tmp = 0;- u% M, |) X4 v4 P8 @; N* ~ l* ^
- u32 time = 0;
( G: f! |$ N: ?# z8 M - u8 res = 0;! o: o4 W1 o2 O. m7 B; h5 d
6 d! E( S( V! [ k9 V- /* Get configuration register, then clear page number */
# D1 }; m$ X: H - tmp = (FLASH->CR & ~FLASH_CR_PNB);3 b8 [; _7 X) r7 j0 a7 `
- 4 a! a$ q! P# R+ \# o2 u* f
- /* Set page number, Page Erase bit & Start bit */
8 V* E! i: A" n J1 P" c5 x - FLASH->CR = (tmp | (FLASH_CR_STRT | (page << FLASH_CR_PNB_Pos) | FLASH_CR_PER));
# K. Y. D$ s% U - # J2 ~9 q, H' m" A9 v& P) e
- /* wait for BSY1 in order to be sure that flash operation is ended before allowing prefetch in flash */5 u# w' }2 ~+ Y* h" ~& h( j H
- while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
5 ?& y# E: _& ^- e1 V+ s! ] - {7 I1 o- v6 P9 v" Z
- if ((++time) > FLASH_OPT_OVERTIMER)
! ~, ]! @; A( x7 g& q; ~$ Q% @ - {5 u9 |0 p/ ^- f: W
- res = 1;& \/ I' d3 @% k7 u$ N0 N! d5 d
- break;% c; M6 ]# ~7 Y) A
- }! ]$ c: _" D: _. A1 I* r G
- }
7 w, W4 M( y# }( H' E
8 a9 r7 X9 |9 F4 O2 U- /* If operation is completed or interrupted, disable the Page Erase Bit */; f4 r4 T" c1 \$ I0 T' [6 |6 @4 R
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
3 q! B+ ~ Q. S) t7 ^* L$ H - 7 y+ |! {$ D/ e
- return res;
b' W4 B8 O& C1 W' { - }
复制代码
# {, D( J2 e/ y: j6 ]$ v5 xFlash忙等待+ D4 _2 Q D3 m$ z5 Z/ Z, X
- /* Wait for a FLASH operation to complete */4 |0 S; g5 u, S' X* E
- static u8 ubFlash_WaitFor_Operate(u32 timeOut)
1 o% v+ {. x: w) R - {. E; q8 w3 g* B, k
- u32 timer = 0;$ B6 b9 q6 f0 p
- u32 error = 0;* u5 p! U# p! G: m# q* p
- `4 k/ X' c+ E3 M0 O3 p" e8 N( a7 V: q- while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
& ~' {& `3 g, [, ?& Q+ Q - {
' h1 ]2 Y# @5 Z: ` - if ((++timer) >= timeOut). g7 {2 U" [! L" m
- {, H* Z- s9 D7 p" @* i3 m/ R
- return 1;* ~) |$ n: V$ n; u
- }
: p& @9 J* z3 ? z$ W1 _+ Q - }
- e9 Z; C* j' R! J
% m& M4 p1 q0 k4 M* t0 [' L$ @- #if ( USE_STM32G0_LL_LIB_ENABLE > 0)
u3 D9 a6 ?0 z9 c- M) j - /* check flash errors */
b- |! b5 a# c- x" { - error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
k b+ ~/ u: ?4 p Q( q# Q" Q - 0 y# E" L/ u" f! y
- /* Clear SR register */
3 [3 y3 S$ ~6 G7 X) M - FLASH->SR = FLASH_FLAG_SR_CLEAR;
5 t5 a% q' j; @* k - #endif
8 t. c) c$ h" x - : E2 _9 z/ i8 F. ?8 s9 u
. P5 Y( U! g% z* V5 B3 A& Y- #if ( USE_STM32G0_HAL_LIB_ENABLE > 0)+ Z& v0 Y+ O: w$ o$ w
- /* check flash errors */6 b) ]! S! R6 }
- error = (FLASH->SR & FLASH_SR_ERRORS);
" q) ?, Q8 M! d9 ^+ U - ; B/ R- v( @8 `
- /* Clear SR register */4 p9 t6 [( w0 y( I! K" Z
- FLASH->SR = FLASH_SR_CLEAR;
/ y: J3 E. j+ H; x6 |/ n - #endif4 u4 b% J |3 I, c+ }
# M9 E9 l: q* W$ f. ]- - ]& Y. @( S( x8 U% v9 v
- if (error != 0x00U)
. X7 ^5 U, C& g% L+ ~ - {" G' K3 u. j- |7 {3 e) w( u x
- return 2;
e* V* P) ^- N' L) { - }% n, X5 v) L* d v
6 o2 t0 X1 j2 s9 F9 }- timer = 0;
. \ A9 `# `: B - while ((FLASH->SR & FLASH_SR_CFGBSY) != 0x00U)
, H E! Y2 _5 F - {' H2 U. m; v' s& ~; b# T; \
- if ((++timer) > timeOut)0 W' l) A$ h$ K
- {. N) H2 G/ {5 q) \1 @
- return 3;
, {# z( t9 e4 }* }, j% M: P - }7 X _5 j, }- ?2 C2 L9 k
- } C9 x- v8 a: s
- ; I9 j* Y8 N. \: Y
- return 0;7 t/ C/ t0 m3 U' c
- }
复制代码
3 Z. a1 a0 F' l! t; a+ rFlash双字写入
7 C0 C l) s& K$ G$ k' F+ `- /* Program double-word (64-bit) at a specified address */
+ v6 d. Q' n3 P0 G. W& _' ` - /* Must EN PG bit before and DIS PG bit after */3 ~- ?* P. R ] z( W( C1 b' Q
- static u8 ubFLASH_Program_DoubleWord(u32 addr, u64 data)
1 G9 J" g* u: S. L' A- P* R - {
0 Y, U; c6 V8 k/ i5 S4 i - u32 time = 0;
7 B5 O) Y. k* h - : T g3 X! m# x5 A3 r% x. R( `+ Q
-
; @7 y5 S# T( Z; o: x - /* Wait for last operation to be completed */
9 E* W: k6 k: U7 a - while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U). c& S* y# _3 R6 ^$ w
- {% s1 J K% U- y. I1 h" b, R+ A9 R
- if ((++time) > FLASH_OPT_OVERTIMER)( @& d3 R0 b$ K; }- O1 P
- {: p3 C0 u1 G# K) `7 ?
- return 1;& ?$ R. z' v* v
- }5 h- l% m& w# D3 Y. m3 c3 m* M
- }* M5 ]+ K4 S+ M( l
-
0 n/ ^' r, q3 _. d/ R' T0 V - /* Set PG bit */
2 ~: O& A5 d( \) w8 k - SET_BIT(FLASH->CR, FLASH_CR_PG);
% \* C9 c0 W4 c1 H1 Z9 i6 P
1 n: U$ n% C; U- f3 ~- /* Program first word */
! h8 D i. P' _ - *(u32 *)addr = (u32)data;9 w% K- a p, B v$ Q/ s
- " i2 q: z8 e, D, s' a4 a
- /* Barrier to ensure programming is performed in 2 steps, in right order i8 @: K: c# B6 E1 { G7 `( h3 s% I
- (independently of compiler optimization behavior) */! O- G) O! G& b, @
- __ISB();
8 y( y" ^, V+ v) K j2 U - % ~8 B: r3 v, i4 F! e# d
- /* Program second word */
4 C& W4 l" B' [& ^3 y; [ - *(u32 *)(addr + 4U) = (u32)(data >> 32U);3 m9 Q2 u0 W+ Z, U
8 F. G7 `; e0 T% [# T8 O* W. U: ~- /* Wait for last operation to be completed */
9 Y$ ]8 F' p3 K+ I - while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
$ A) } r9 i# Y0 I - {
, }4 ^, \5 C" C& E8 N( m - if ((++time) > FLASH_OPT_OVERTIMER)# i/ Q0 \5 _: U6 b* t" Q' E
- {
) ]- H; m, w7 y3 z) t - return 2;9 Z0 L% m- D( Z7 D
- }
[! \: R' t+ S* J) M - }1 @. g8 y7 T) F9 P( b0 T! b
- & Y: ]" Y: k5 v3 `' z3 i
- return 0;, Z6 c0 k. x1 d+ g/ q8 g
- }
复制代码
7 G. M) W+ t1 d5 M7 Y8 n; SFlash LL库双字写& i/ T* k& \* O% w( J
- /* Program double-word(64-bit) at a specified address */
1 ^& z" [% Q g$ t3 { - u8 ubFlash_Write_DoubleWord(u32 startAddr, u64 * pDat, u16 len)
2 N3 D% N+ R3 ^4 B" {" A6 i9 w - {1 d# q M! H u
- u32 page = 0, time = 0;
+ h0 G6 A5 l" i, } - u8 tryCount = 0, res = 0;
7 C+ W: s5 k0 m" [: N0 ]2 `6 `2 t - u16 i = 0;
- G7 o) s: f3 O6 s& @: C" Z: h2 J - 2 _, U) X: e- K. l/ o- l0 a
7 C8 O' i" i( R# P2 W- FLASH_UNLOCK:
# M" I C$ K- z: j' Z* c - if (ubFLASH_Unlock())
0 R- _5 ^& X' c1 o1 e - {
# N3 v! H, p) [. `1 P5 d' I% B - if ((++tryCount) < FLASH_OPT_TRY_COUNT)2 r& K* h( s4 U3 o& {, ]2 R6 O
- {; [2 H& r1 t- |% a
- res = ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);! X' N/ X$ k4 J% g. N# U
- dprintf("Wait For Operate %s...%d\r\n", (res ? "Fail" : "OK"), res);% c, I. \8 l6 k* ]
- goto FLASH_UNLOCK;
$ Q8 Y1 k0 }4 Q- A - }+ h$ @# F% c/ C+ \, H- z7 E& l
- else& O$ Z' p- `& s* ~2 E R9 T+ @
- {
1 B, }! F! r d$ }* d' x - dprintf("Flash Unlock Fail...\r\n");- M2 a$ N* H7 o+ F
- return 1;
+ S5 ]; ]* J: z' ]- g8 f4 a* a- _ - }
% Q/ e3 ]0 w0 e d - }
; z( }. c& v( h! V- k - + i, ?& G9 K$ L0 ] H
- page = ulGetPage(startAddr);# H V) L' ~6 J! w0 g8 v
- tryCount = 0;
/ d5 Q1 f# L0 k8 D4 ]% o; n4 y6 I
3 e7 ^ v2 `: b3 v) z
) d. k0 Z3 \, W' x, a- FLASH_ERASE:
6 \% Z3 o/ I0 L' _) J - if(ubFLASH_PageErase(page))
! v+ x1 e1 W4 Z! D - {2 A: O n( ^* B3 C0 p; d8 [
- if ((++tryCount) < FLASH_OPT_TRY_COUNT)
6 m! a3 }% M7 @2 p. B - {$ J$ v. o$ ]+ k% L
- res = ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
! w# F7 C0 F* ^ z P6 c - dprintf("Wait For Operate %s...%d\r\n", (res ? "Fail" : "OK"), res);# q6 Q; w/ \, E2 S6 g8 g
- goto FLASH_ERASE;4 E+ ?- V6 q& \) {! q! o* b
- }
. Q) W0 R0 G& [! W( W" Q - else
" g8 p# q2 C! Q8 x - {. g+ m. ~% S+ i) P. W, [0 P8 }
- ubFLASH_Lock();
, c E1 o3 K2 u7 \% k1 H - dprintf("Flash Erase Fail...\r\n");; O4 h3 u( C0 H, d- J1 ?
- return 2;8 r& T( F& I: ]1 A
- } 7 i6 G. ~- Q; } G" e5 Y. q
- }
$ }, @: w2 Q: |0 X& ? - - j5 S2 Z9 d& N( g
- / Y$ c; ^. @- j; h, O
- tryCount = 0;
5 X7 A7 i& G, f$ j2 m, Y0 X/ y - for (i = 0; i < len; ++i)$ r% ?. g3 E7 i/ e1 s; I# V
- {
5 }; h. Q/ Z+ w N9 [ - while(tryCount < FLASH_OPT_TRY_COUNT)
- ^* p$ F! G" Q - {: h |4 j; c( W
- if(ubFLASH_Program_DoubleWord(startAddr , pDat<i>))
T& H$ \5 a/ }2 ^% k& ^. ^7 l - {
& e8 R. o! H$ D8 B& [ I; e' r* ]9 i* _ - res = ubFlash_WaitFor_Operate(FLASH_OPT_OVERTIMER);
3 s. r% z1 F$ m& F! M' L$ {6 a# t - dprintf("Wait For Operate %s...%d\r\n", (res ? "Fail" : "OK"), res);
* W8 e2 n3 M) S' Y6 s7 ? - tryCount++;
! a( D) k u" C: D7 W - }- e- |6 \2 x' B' W% D- t
- else
+ v+ K) v3 O, I! z$ R( ]5 D - {
. m/ ^9 h1 Z$ P& X3 H# k - startAddr += 8;
) m7 p& u0 l; P6 Y - tryCount = 0; F; Y+ q0 V( h A. a8 L& {
- break;
3 V& `& q5 @7 Y+ N+ l - }8 y& W5 ?3 |9 b1 ]/ S
- }- {' P; E7 y7 A
' x- ~! e X' L* l) e# c% p- if (tryCount)1 t0 F0 B/ p6 T* J
- {
6 K- [3 Y" S/ T' B: R. e0 p - ubFLASH_Lock();1 `( B( L- p# w0 r
- dprintf("Write Flash Fail...\r\n"); R" t r" q+ X# V. l+ P: Q! _2 K
- return 3;
& K( r' |; O; M0 s1 G& H - }
6 P" D; Z, b3 H - }7 T* |- G) X# w5 T
6 C! y7 J' k- p- * k0 _6 t* [+ j( y8 Q/ [1 z
- ubFLASH_Lock();
M" j' Y& y5 \ - dprintf("Write Flash OK...\r\n");
* o, D8 N; ?5 v5 q- u/ Y - return 0;
" W4 v" @2 X8 p - }</i>
复制代码
0 q' f) s7 [' G; H0 x; eFlash HAL库双字写
: F; v ^; V( b) `/ J/ k, h- /* Program double-word(64-bit) at a specified address */) \, d; v7 c1 Z9 k& v
- u8 ubHAL_Flash_Write_DoubleWord(u32 startAddr, u64 * pDat, u16 len)
Q6 d9 v/ O9 O" w0 [) X- W - {) u: Y/ j% `+ i/ t, a
- FLASH_EraseInitTypeDef EraseInitStruct = {0};
9 j# _4 Q s2 F" _0 i - u32 pageError = 0;6 W# \; l- u+ \. C
- u8 i = 0, tryCount = 0;+ _ E) Q+ D, x& j [6 f6 t% l
- 7 p- W( r$ x+ H# E a' K/ [
- # A; |+ S( I3 {0 a4 h5 m
: J; F- T/ U* [+ K, ~- EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;+ r1 Z; D- b; g) y
- EraseInitStruct.Page = ulGetPage(startAddr);
6 k9 n+ ~7 f! Y: u3 d9 f5 I - EraseInitStruct.NbPages = 1 ;# h8 \1 X' U2 ^
- EraseInitStruct.Banks = FLASH_BANK_1 ;
, I! G5 R' J9 b) u" N9 C3 k
9 \1 ~1 P8 i- D$ }7 a- 9 e* L4 v2 J& b; v8 q+ r9 k7 F
- FLASH_UNLOCK_TRY:) R1 q' d4 w7 F( i
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY) != 0x00U)5 k3 h3 ^9 L- \& N
- {
) ?1 _& T2 \9 F( u) @ - *(u32 *)(startAddr + 600) = 0x123123;
8 t1 b0 _4 L+ ^( I3 x p - FLASH->SR = FLASH_SR_CLEAR;# i' D, X" U( A; C. N: D. o7 h
- }
7 V0 X6 U" d! _8 o
V; F; D( F/ n X$ S0 e @- if(HAL_FLASH_Unlock() != HAL_OK)
7 q/ |8 S2 M1 Y; r8 X1 X7 ?% ^ - {
0 ]7 K1 f' ^2 g. J5 g( I B - if ((++tryCount) < FLASH_OPT_TRY_COUNT)
4 l3 N0 H' K, q - {! @3 i2 S* k8 Z, m- |) v S
- FLASH_WaitForLastOperation(50);
2 T8 Q' W( ]9 i7 L- m. ?7 Y+ t7 w7 \ - goto FLASH_UNLOCK_TRY;0 Y' a$ D% { n
- }
2 p5 o) z" }# K! }7 t - else
% O; b3 ^; k; s$ ]% T - {! x5 i2 ?9 ?! i' p5 H5 D7 C: h
- dprintf("Flash Unlock Fail...\r\n");
/ E" j: C7 z+ b* d+ x - return 1;
* c1 g4 t# G$ S4 p - }& k: f" B* P: l- |! o
- }
. {% n2 W: D6 b' F4 s: d
5 r8 h* @. g7 v3 s; J* @4 W- tryCount = 0;% u% j ?) \1 W5 |' ]
- & q5 I/ W7 J, \6 I0 r' V- q8 n! R2 U
- # X6 J n, S* d, N" ]
& `" d/ }) B5 j/ p- 4 l0 W% V: {$ b, m
- FLASH_ERASE_TRY:
4 D }+ B# B. m# X& I: F9 v0 V - HAL_FLASHEx_Erase(&EraseInitStruct, &pageError);$ t$ e& P4 q# |6 q
- if(pageError != 0xFFFFFFFF)
; c6 V+ j5 f4 y4 {6 y5 E - {5 ^5 h2 i7 j6 p9 i
- if ((++tryCount) < FLASH_OPT_TRY_COUNT)
4 `7 v9 ~- M+ |+ c7 a7 z - {8 M4 x5 ]: c! R9 ~1 K" ~* O4 p
- FLASH_WaitForLastOperation(50);6 z( X- T! \9 M
- goto FLASH_ERASE_TRY;
+ v/ }, z. X7 O9 l6 N% Y; x - }
0 X, X5 A0 X" h3 c; Y9 B$ Q - else
" _* ]" g! z, }0 e( L$ @ - {
$ a' u- ?1 i5 X E/ Q/ T4 M) p - HAL_FLASH_Lock();/ b* g% ] D- Q* E
- dprintf("Flash Erase Fail...\r\n");
7 t L9 M4 V( O. i! ?3 ^$ v9 g0 Y - return 2;# a1 r1 w0 G4 y; Y
- }0 L7 |' t8 N1 P. J) ~
- } G# b% ]! p- X* e
- 4 w. x4 A5 l) F; i8 [
3 r8 Z) d- {1 V0 b- tryCount = 0;
7 l5 h5 C) R' ?& a+ ` - for (i = 0; i < len; ++i)
0 V! K0 U* [( L9 F, S/ m - {& E8 ~4 \6 \3 ]5 k
- while(tryCount < FLASH_OPT_TRY_COUNT)% F5 A! @* S& G* t
- {
' r2 U" O Q6 d3 h5 a3 r- L8 x! S - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startAddr, pDat) == HAL_OK). {" x5 t2 J G0 P+ n$ Y" q8 d
- {
W" I8 I! R+ S7 K2 k A. Q - startAddr += 8;
2 B# K( X2 I9 l# H( W* i - tryCount = 0;- U4 o, F; ^0 L3 `' T* i4 n+ a
- break;
# ?' f5 Z! s F/ p3 `& \ - }
. ]% `. v+ C$ W4 S y; l - else
# ]* |- y q: l7 z - {4 h$ G V& a% [, r6 |
- FLASH_WaitForLastOperation(50);! n' k F8 Y$ L5 o, O) M
- tryCount++;7 [& z4 q" L; u: i
- }- G4 x* X; e* |, k5 ~
- }
7 k: q u2 V! b4 f! v
% t0 U& n% Z) O! V0 y- if (tryCount)0 j* P( c) h/ N' Z# g/ N$ b* z. ]# T
- {3 i) x( V/ G9 w$ n
- HAL_FLASH_Lock();
' ~6 z0 d/ g# T4 [ f' a - dprintf("Write Flash Fail...\r\n");) i0 O1 Z. z; P F0 I) b" B
- return 3;
, l6 \- ~; P" g' A - }
, u4 x6 E/ s: c1 j - }" B! g) P* x n0 _& K
- 0 j4 V% P" N Y
- X: K8 `: o1 l% f- [
- dprintf("Write Flash OK...\r\n");' Y# {& Y$ U2 C, p* F4 R0 A
- HAL_FLASH_Lock();
( F9 e9 v% R: C# L9 I - return 0;
: ~5 L8 L+ F+ O4 [4 Z6 ~+ ]( i
: h1 g4 z/ j7 R* J" ~- }" ]" J+ g0 M9 Z% M, g9 S1 [
复制代码 b$ q& A F6 j& H: i- K
Flash双字读8 y6 r5 Q! @* q
- /* Read double-word (64-bit) at a specified address */
/ T- y2 ~3 ~ ^" B0 | - void vFlash_Read_DoubleWord(u32 startAddr, u64 * pDat, u16 len)
1 h. p6 @; {6 Y: n, X - {; J9 O; @9 E0 f2 J
- u16 i = 0;* s% T/ r5 [9 c5 x& L
- " k8 l! S8 a4 o
- for(i = 0; i < len; ++i)" c, s9 {4 w6 M! d" a) G
- {
7 T* g6 h8 r" ~, `$ C6 X - *pDat++ = *(volatile u64 *)(startAddr + (i << 3));
0 D* b. k1 E" G" j5 U$ g. Z ]$ _( w - }3 p- p1 `* p5 T4 V; h0 S
- }
复制代码 2 U5 }& m, t/ `2 d5 a: e/ q- m
Flash读写擦除测试+ G X) ], s# i! V: g3 @
- typedef struct9 _* _# X. @6 R- S- ^
- {1 o1 T' F/ d& Y
- eBatteryCap eBatCap; /* 电池容量 */
. u4 i# R# O/ | ]% l0 L" y - eMeasUnit eUnit; /* 测量单位 */2 O. W. ^% k4 O$ L
- d4 ]9 R# N5 R& |3 C7 q- u8 LowBatFlg; /* 电池低电标志 */; `1 }8 g! g* _1 w7 c$ D
- u8 MeasType; /* 测量类型 *// A$ Q: o T& }. n2 X$ _1 j
- u16 MeasMaxRange; /* 测量最大量程 */- _' P; S& W: Z" h" ~9 g: E% f* q% I
- ! p5 X4 ~0 y6 E' Q& r2 Y/ R
- }GlobalParamStore, * GlobalParamStore_t;
2 ~+ u; [8 ^; O3 M# g9 U2 S) p - 8 W; s) S" k" O
- ) }* D: A; {' h( J$ C: ?; a
- typedef struct
( s d( R' s( F; R& D% g - {- d' R8 b- J( d6 Y/ K
- u8 AngleDemarFlg; /* 角度标定标志 */
- i6 C0 h1 u$ T8 t/ @( ~. c4 M - s16 AngleDemarVal; /* 角度标定值 */
# g# Y2 d5 H1 f n6 H" v7 x - 2 c- w. D5 V3 R; L2 x5 T
% D4 D c! n- b0 g) g, P- u8 GyroCaliFlg; /* 陀螺仪校准标志 */
1 B* L5 r) s e" G k - s16 xGyroCaliVal; /* x轴陀螺仪校准值 */
: x7 b# R! {! N+ V - s16 yGyroCaliVal; /* y轴陀螺仪校准值 */0 I) T M' b: z
- s16 zGyroCaliVal; /* z轴陀螺仪校准值 */) O+ l Z$ o5 ]* ~' T
$ ~8 `1 r7 M$ A# E! ~- 7 ]( `7 D ]. a" ^
- u8 DistDemarFlg; /* 距离标定标志 */- Y( R5 p0 N9 V- t# t1 f
- u8 ZeroDistDemarVal; /* 零距离标定值 */! w( J& {0 {* r2 ]
- u16 FarDistDemarVal; /* 远距离标定值 */
' x! F4 X ^! D: q" a' m - }DemarParamStore, * DemarParamStore_t, * pDemarParamStore;
" z+ B6 A$ q; O* {% g0 ^/ {) X
8 x$ B8 W- V( N% n- typedef struct; S; B$ n+ U9 @( ^0 L; w4 U7 T7 c: E
- {0 U% ]$ |8 ~, K7 [: Q6 `- c/ P M
- xSuperProductInfo ProInfo; /* 产品信息 */
1 M9 \5 }8 M L" Z% \* X: ~* C - GlobalParamStore SysPar; /* 系统参数 */
0 C3 q# V: D( U$ Z2 G - DemarParamStore DemarPar; /* 标定参数 */6 @) H8 q& p" \! m" W, u8 L
6 d9 y1 i# d8 J, D( T% x
' z+ r% P+ @8 N) A- u8 ubRes[1]; /* 预留 */- m2 ]) j3 P- \5 d* j( M7 _8 Q) N e' d
- u8 ubCRC8; /* 校验 */; `8 f; d0 j8 o% [8 C5 t" _
- }SystemParamStore, * SystemParamStore_t; j* y- |, I% m9 \9 Y+ V
/ D6 j% D7 q$ Y# c6 q% I- - R9 n9 W C6 p0 [- U# C7 Z
- 8 W/ v9 ?/ ~( n4 P& d
& _* J; w) L6 C2 y- : t& Q+ Q* b7 s2 S
- SystemParamStore SystemParam = {0};: i5 N" N# n' r
' y7 v8 M! H" x: x, ?- /* 保存系统参数 */% r6 V4 [% M" E& \" n+ v
- void vSave_System_Parameter(void); V$ U6 |, z. O
- {/ Z( B) S3 m8 \* l/ b
- u16 len = 0;) Z# E5 z1 L( i4 `/ X& e# Y
- & P" }/ T3 T) x9 A l* _
- 1 h0 H8 x' d' K6 p
- len = XMEM_ALIGN_SIZE(sizeof(SystemParamStore) , 8);2 w1 S& D! U6 ^% l$ V9 w
- if (len > (FLASH_PAGE_SIZE >> 3))
, }0 ^# U( l& k+ @4 } }& [ - {
: g/ Q }. [; ^ - dprintf("System Param Over Flash Page Size...\r\n");
9 B/ S$ q) x& b" _) W3 O- {4 U - }
' ^) F- g# A! N" i - else4 Z$ x: [9 w; f$ ^) Q( r
- {# p/ t. I# G& L1 b! |9 B4 K
- vSynWrite_System_Parameter();
% V/ `( N7 _3 b - SystemParam.ubCRC8 = ubCheckSum_CRC8((void *)(&SystemParam), XOFS(SystemParamStore , ubCRC8));
P5 ?! u/ F3 x2 g! u t* ]6 w5 w! Z - dprintf("SystemParam CRC8...%X\r\n", SystemParam.ubCRC8);
$ |; ]" s* K5 x' h - if (ubFlash_Write_DoubleWord(SYSTEM_ARG_STORE_START_ADDRE, (u64 *)&SystemParam, len) != 0x00U)9 v+ k) U" q) C' h2 d+ L8 o J
- // if (ubHAL_Flash_Write_DoubleWord(SYSTEM_ARG_STORE_START_ADDRE, (u64 *)&SystemParam, len) != 0x00U)4 P, N/ D* E, e/ Z" v
- {3 c9 b( F# P( y0 L* f
- dprintf("Save Param Fail...\r\n");3 @) L% q7 J) B$ W8 N$ W5 Q
- }
8 W0 x S" I/ _" K - else: `' H% v4 b; I* Z# c, \$ j% S
- {* v' P1 x# Z6 [; z7 k: s: p
- dprintf("Save Param OK...\r\n");& x; W& \$ d% Z7 m" C: I2 B
- }$ W7 c: `8 l2 g. S9 M. F H; J
- }# z9 a0 ~3 y, B' u
- }
( \5 w6 ]: M! V- z. a - 7 i% v1 l* R( W: W
- $ O% K4 I) \- V1 ~. I' @
, |3 d0 K8 Q8 l+ w7 X8 T- 0 ~1 Q3 x0 e& t, F6 v
$ P! S& r- N; ^0 T& h* j- /* 读取系统参数 */
( [7 q6 v( R4 _- ~/ g - void vRead_System_Parameter(void)! R2 Y/ b' A! }+ f
- {
. g! g( ^) Z% I8 D5 W - u16 len = 0;
3 O! c; i( `) l) u - u8 crc8 = 0;
# R& M9 @+ {* |/ H) T( }( @; L
* {( @# [, r6 Q, x: ]* _- . r& Q6 T, K6 U! f/ P* `
- AppProInfo = &SystemParam.ProInfo;, z: C8 o& ~# [2 ~4 Y6 J
- len = XMEM_ALIGN_SIZE(sizeof(SystemParamStore) , 8);4 S$ E3 I. ?# P; g H
- dprintf("SystemParamStore Size:%d %d\r\n", sizeof(SystemParamStore), len);
& B2 w+ U2 U3 T' V4 m- }! a l - 7 p8 `8 Z; i! x% e: ^
- if (len > (FLASH_PAGE_SIZE >> 3))( S! \; k+ s( `# w
- {0 u9 t5 K1 }! L
- len = (FLASH_PAGE_SIZE >> 3);% ?7 l2 B( a; q7 \, Y; {
- dprintf("System Param Over Flash Page Size...\r\n");
$ b# j0 e: Z) T; c - }( S1 A Z0 X2 ^( R# {3 P
- 5 W) }6 u- b4 N! G( r
-
0 E# x* O+ M2 i - #if 15 S0 ~% W, b, w Z( R+ H/ Z
- vFlash_Read_DoubleWord(SYSTEM_ARG_STORE_START_ADDRE, (u64 *)&SystemParam, len);. E: u5 W& {. B0 A
- crc8 = ubCheckSum_CRC8((void *)(&SystemParam), XOFS(SystemParamStore , ubCRC8));- _0 f! o# Y: U! m" [1 `
- if(crc8 != SystemParam.ubCRC8)
3 S6 N( H* v* w* j - {9 W g/ a2 n- N4 k! e
- Restore_Default_SystemParam();
) K. P( U8 ^' R# {: z9 u# R8 S - dprintf("Restore Default Param...%X %X\r\n", crc8, SystemParam.ubCRC8);
G9 c- {$ Z. E. r- V( } - }4 w# w4 Z$ Z0 n
- else5 [+ [" Z5 C) H. v! R+ o. W
- {) P9 s* W8 G& M* E* I7 Q
- dprintf("Read System Param OK...\r\n");
: i8 b# ?" C8 m0 ` - }0 }) G r" b: o7 E7 J
- #endif
. u- |6 U% }1 D) W - ' @( f$ U; X- s, f# U+ U
- & N% O& q4 z% E0 \7 B# A4 E
- AppProInfo->DevInfo.SWVer.MajorVer = DEV_INFO_SOFT_MAJOR_VER;1 ]( H* Q: U% Y
- AppProInfo->DevInfo.SWVer.MinorVer = DEV_INFO_SOFT_MINOR_VER;
) x) R) o5 @( b: K% x6 o8 B - % B3 B$ q1 }. |# q/ W9 [" e" }
- - I0 l7 T7 ?" }1 ]% m
- vSynRead_System_Parameter();
% v8 |6 l* w$ M: o - 2 W/ a. `0 P, S: W' m8 |, I
- // vShow_ProductInfo();
4 u6 {# T: \1 W$ c# G: o - }
复制代码 : k1 n% R7 |- P$ {
测试情况
2 E: I- c( I( Q2 @! v- Init UART OK..
& B7 C4 V3 n; m& \! A4 f2 l' I* w - Vref: 3298mV
$ {& Y" ]; F- h7 |, { - SystemParamStore Size:88 11
: Y1 V% f3 n6 i7 ]# q% \ - Read System Param OK...
U$ H8 }4 H6 }8 W - ******************** System Parameter ********************
5 x: j; k) A: M9 @' ?0 A - Meas Masx Range: 20000dm
% A' u7 N+ Y8 h0 k$ q - Angle Demar : 0 ==> 06 \4 ^$ A0 W! w! M: V$ z9 g7 p
- Dist Demar : 0 ==> 0
) m( Y. j! r; x) {5 A& O) p - Meas Type : 6: t! _1 g; \$ B* ?' m1 Y. G
- Meas Unit : 1
) @5 T0 c0 F; v - Gryo Cali : 0 ==> 0 0 0 x0 O- H7 X7 y" y" P- u! \- j
- **********************************************************
- k, n* @- z8 L - Gyro Type MPU6887 ID 0x0F
/ i) j# N8 J4 M; s4 H$ ]( g - Set Meas Type: 6
8 [: g7 }' \' `& V/ b - Shutdown OverTime: 20s) y c0 h6 \ r: ?, w5 Y
- Bat Sat : 0
$ ?' T! m* \: Q2 y - Set Meas Type: 2
% K# Q6 v! @) ?+ t7 H3 ^6 ] - Set Meas Type: 9
0 \ N* s, r4 x0 c& t- U) g - Set Meas Type: 3
9 C) s& N0 b5 w g - Set Meas Type: 5
+ ~" U j L) j4 q3 X3 o* w - Set Meas Type: 75 s; c9 H6 K8 V B! h: F( ~2 H
- Set Meas Type: 87 P, g3 J6 _) v5 E3 I+ c, @
- SystemParam CRC8...E7
: P) ?+ E2 p2 ], J8 J& e5 P. M4 p7 \ - Write Flash OK...
% {' @" a- b% S8 {6 H; ^ - Save Param OK...
6 `4 L- A/ j0 c- B - Overtime Shutdown.../ j4 N4 W$ j. t$ d+ `' m
- ( w Z' {% z! a" v) M
- Init UART OK..1 O9 y' S. w% V9 k R/ H3 M; l- S
- Vref: 3302mV
v. l& G/ X( ]2 q0 B - SystemParamStore Size:88 11
' E) Y$ V* Y4 i. |+ X6 _; k - Read System Param OK...
6 R7 `. Q3 b7 D j5 y - ******************** System Parameter ********************
! g% e+ i2 h/ t! `, ? - Meas Max Range: 20000dm
1 W# o! ?& J: z3 p - Angle Demar : 0 ==> 0# t, C( v* E) u/ s: G* L( c
- Dist Demar : 0 ==> 0/ q( W: O9 B: `2 A! d, o( S
- Meas Type : 8
2 l8 \( ?5 {, E - Meas Unit : 1$ X5 l+ N$ Q: A/ ?
- Gryo Cali : 0 ==> 0 0 0
7 }3 P& l' n/ w' ^ - **********************************************************
' F3 u x# |" S* [9 _5 j2 h1 i( d - Gyro Type MPU6887 ID 0x0F; q7 F0 k, _7 _: D( N
- Set Meas Type: 8
1 ?, V- H3 W6 U+ r( k - Shutdown OverTime: 20s. _, i2 w, j! e3 O. T
- Bat Sat : 0$ e% V3 w* t, p! f, _
- SystemParam CRC8...E7
. E( M% o) d0 r - Write Flash OK...
- e8 l) @8 |% t! M, x5 |, m. `3 M+ S - Save Param OK...
) P( |* P' K4 n8 t - Overtime Shutdown...
复制代码
' d4 ?6 I- F0 j! o @/ y" B( ^6 }————————————————
& O* c. N; K; q* z$ S版权声明:凌盛羽% R) `: j0 \2 n4 @
2 K9 P. ~' w& Q7 {" D" w) C1 I
) B4 T4 D: B" }, g Y; T9 b1 l* S$ z. n. [- H8 l" M h: u, s
|