你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32 OTA的读写FLASH

[复制链接]
攻城狮Melo 发布时间:2023-3-21 16:51
读写FLASH0 g* K: G. W" N
1. 简述

- [) X3 \/ s: N9 e. p& \" H0 f1 fSTM32的写FLASH相对简单,直接读即可,写FLASH相对复杂。首先看STM32的内存大小和分配。
5 g; |+ g; ]: y3 H
2 S$ s# y$ j6 o. S- ]. A用到的HAL库函数:
7 s, e1 ~1 [9 |$ }1 Z- G
  1. HAL_StatusTypeDef HAL_FLASH_Unlock(void);
    9 {" o1 E* A1 ?
  2. HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);
    / Q. Z9 L# Z3 ^0 X* [" ^& o8 Y
  3. HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
    1 g1 w! o$ C$ U9 h1 i9 {; w* E1 _9 L
  4. HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);$ {7 I7 I* b/ l& \& D
  5. HAL_StatusTypeDef HAL_FLASH_Lock(void);
    1 T- _$ Q" c8 y5 q5 `
复制代码

4 n/ T1 b) ~: v5 }, {% Z: V9 a2. 读写FLASH代码
  1. #define STM32_FLASH_BASE 0x08000000
    . h( _( H+ Z) a8 E- s& ^* q" S* [/ L
  2. . |1 C* t# W; \5 ]: Y8 H( ^' W
  3. /* 获取扇区号 */; l; r  E% e" o6 g
  4. static uint8_t bsp_flash_get_sector(uint32_t addr)( S$ ^* q! M, Y3 [& P- W
  5. {) P' S7 [) v+ M
  6.         if (addr < ADDR_FLASH_SECTOR_1)       return FLASH_SECTOR_0;
    " q( S- s( {" i# L7 x# G2 q6 p% w
  7.         else if (addr < ADDR_FLASH_SECTOR_2)  return FLASH_SECTOR_1;3 {7 i- Z) M$ a3 ?& t& j0 T$ o5 ^; o
  8.         else if (addr < ADDR_FLASH_SECTOR_3)  return FLASH_SECTOR_2;
    / d% }% Q! n& A# U' Y% b
  9.         else if (addr < ADDR_FLASH_SECTOR_4)  return FLASH_SECTOR_3;- f9 k& E- k7 Y1 c& a4 y# o
  10.         else if (addr < ADDR_FLASH_SECTOR_5)  return FLASH_SECTOR_4;
    0 Z; H3 w3 y1 x. `1 N
  11.         else if (addr < ADDR_FLASH_SECTOR_6)  return FLASH_SECTOR_5;+ Y" B/ Z/ |: \$ \4 z2 y% ^* Y
  12.         else if (addr < ADDR_FLASH_SECTOR_7)  return FLASH_SECTOR_6;
    + J9 K# Y3 H0 |9 _
  13.         else if (addr < ADDR_FLASH_SECTOR_8)  return FLASH_SECTOR_7;( g7 A5 ]$ B" Q+ f
  14.         else if (addr < ADDR_FLASH_SECTOR_9)  return FLASH_SECTOR_8;
    # B5 c8 @3 `9 e- u4 B4 D3 f: @
  15.         else if (addr < ADDR_FLASH_SECTOR_10) return FLASH_SECTOR_9;' T7 h" U, `) a& c$ d% e# B
  16.         else if (addr < ADDR_FLASH_SECTOR_11) return FLASH_SECTOR_10;   
    - x; j# s% d" D7 f0 d
  17.         return FLASH_SECTOR_11;        ( c0 F. P$ C) V, ~- l  X" f' L
  18. }
    # v1 R( \7 w0 U
  19. 1 r7 ^0 K) m& g' p6 K* B3 f7 K% @5 k; Z
  20. /* 读FLASH */9 u7 n" G8 Y: C
  21. uint32_t bsp_flash_read(uint32_t addr)+ Y) J3 n* d; r' C# c
  22. {1 M( w! p& d8 E  o6 Q  a
  23.         return *(__IO uint32_t*)(addr);
    & g( Q; V6 C  I# u) v, C* I9 d
  24. }
    + a3 n  i# E, I8 \: S

  25. ) l; U3 v' L* t, [: r% e( N
  26. /* 写FLASH */& ~3 s! P( B: S/ n% @* R, m
  27. void bsp_flash_write(uint32_t addr)
    7 x8 s% y* D3 C2 R; {) [4 h4 t# S
  28. {8 e- `* Y$ q: z/ B- V' m' ]( J
  29.         FLASH_EraseInitTypeDef f;, N) u/ h, z" m+ x# B
  30.         uint32_t sector_error=0;
    8 `: k# r6 i" i/ J2 B" u6 G( Z
  31.         uint32_t start_addr = addr;
    / e- x  \, z7 I+ Q
  32.         uint32_t end_addr = start_addr + (size * 4);4 h/ f* j. k: g/ ~, P1 A6 w( e
  33.        
    + n. O- n% A+ d
  34.         /* 1. 判断地址合法 */' Y0 k  [7 m8 b$ v* I( E
  35.         if ((start_addr < STM32_FLASH_BASE) || (addr % 4)) return;/ ^& \6 k' h0 s( G9 L* w
  36.         0 G0 e+ t* q  y/ z
  37.         /* 2. 解锁 */
    % ^& t' Z( \# Q. r( G+ j. H
  38.         HAL_FLASH_Unlock(); ' G+ H5 L9 K0 u* X
  39.         1 H2 e6 R4 w) ]) g% a2 J
  40.         /* 3. 擦除 */+ T# N" q5 R  N- O+ H) W; |
  41.         if (addr < 0x1FFF0000) - E' G' P; P4 X; K6 C2 z+ b
  42.         {4 n. s5 n: Q; }0 f$ A& a! s& D0 D
  43.                 while (addr < end_addr) , T5 m* Y7 Y4 S5 y3 {+ b1 Y
  44.                 {
    7 w. |9 u! h# h% K% k1 M1 m$ }; V
  45.                         if (hal_flash_read(addr) != 0XFFFFFFFF)
    8 R1 A% M* l2 t9 {
  46.                         {
    4 Y8 Z/ L2 k" G$ i# o3 ]
  47.                                 f.TypeErase = FLASH_TYPEERASE_SECTORS;1 A" \+ y) _3 U; Z3 L
  48.                                 f.Sector = hal_flash_get_sector(addr);
    ' Z. A- o2 R! f+ M) D" B
  49.                                 f.NbSectors = 1;$ T" k' X6 H4 x8 z3 f, |
  50.                                 f.VoltageRange = FLASH_VOLTAGE_RANGE_3;5 q2 R* S* N6 {" C
  51.                                 if (HAL_FLASHEx_Erase(&f, §or_error)!=HAL_OK) break;5 M- o7 w4 w- N8 t
  52.                         }
    , T$ Y3 ?0 w7 d4 m8 A
  53.                         else addr += 4;     9 v# g1 B1 J+ Y0 D
  54.                         FLASH_WaitForLastOperation(50000);* @3 w+ _! I" K& m2 ~( o
  55.                 }! U& F' E$ x* N0 i
  56.         }
    3 C' h/ d, l# Z9 f& Z$ g
  57.        
    4 x9 A" u7 a9 u3 [2 s) F$ U% i
  58.         /* 4. 写入 */9 n% w, f+ e" X: U; h# l2 ]. `
  59.         addr = start_addr;) g% I$ V% [# u& Y, i
  60.         while (addr < end_addr) / D6 a+ t5 x2 p4 J" F) e+ B! o
  61.         {
    . ^8 G6 A7 f/ c4 u" h
  62.                 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *data) != HAL_OK) break;        ; }8 J% l9 X0 h
  63.                 addr += 4;
    % T# {- h6 {% Y1 P/ E/ O. O, `% \
  64.                 data++;, M; k' Q5 ~: O2 c) [8 g
  65.         }/ `3 n  ]* j9 Q$ d* {. r
  66.        
    + Y7 x) l$ I- H4 o) i) f; s
  67.         /* 5. 上锁 */$ C5 {$ H" |+ U3 V) X, t
  68.         HAL_FLASH_Lock();    $ v6 l  S5 X5 f: v+ N8 I! y
  69. }
复制代码
: a' Z+ z% U3 ^4 C4 g
————————————————* A& m' E: w: h0 e+ u2 m
版权声明:lljwork2021) s( L: G4 u+ b/ \% {- P! s4 `* w
. x0 N9 |8 ^& g6 s" a0 J
9 ?9 a& [9 V/ A3 j- }( o- u
1 k! n. A" X( J9 F- g
收藏 评论0 发布时间:2023-3-21 16:51

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版