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