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

基于STM32H7片内FLASH编程失败的集合

[复制链接]
yumeii 发布时间:2019-12-24 12:49
有人反馈在产品项目中使用STM32H743II芯片,在对片内flash进行编程时遇到点问题。
2 s' Y+ C! K, ~5 s* m) s* }0 S  A6 N! F+ N% |( Q; ?  h( I1 _

" v/ D: \# v( f2 X他将片内的第一、二扇区存放用户应用程序,第七扇区用来存储网络应用相关的一些配置信息。他写Flash的过程及有关现象是这样的:% f& B# V* H0 I+ _- F2 e

3 T( u/ Y% e4 a; ]; @: a* h% c7 Q

7 S- g; ^& h/ k* C关中断->解锁flash->擦除扇区->写入数据->上锁flash->开中断,写入的数据总共40个字节。可是写完之后再去读时,发现只能读取前面32个字节的数据,在调试过程经常莫名其妙地触发硬错中断。这是怎么回事呢?
1 M" e) S) v8 w7 V. \6 f9 ^5 L
6 w& T* X  E6 b9 p6 s

' I" O1 _; @1 h  I- V; J根据该STM32用户的反馈,基体情况就是对片内FLASH进行写操作不成功并衍生出相应问题。
, |  @: X' T  C: f4 C1 |! v6 v6 I/ f6 Y& W6 X8 @) ]3 P  Z

) _2 n0 Q: b& Z$ x我们通过查看数据手册,不难得知STM32H743II片内FLASH为2MB,分为2个BANK.
3 y8 f1 C: C7 v4 r6 g
0 L! j8 s$ i4 e& G1 y( s! X
5 U3 E0 O  d5 r, m$ i: @9 U
1 (2).png ! W6 W  x5 @4 y6 e( |! `# M3 B: h

' u. [  D1 C/ A; g4 i  V

. W  U7 q. j" R7 o  F9 \0 F: K片内FLASH布局如下:7 G4 }6 w/ {/ q

: j. m* k) \3 F$ h1 D

8 [" h: G  }' V 1 (2).png ' h3 a7 B6 W* w4 L+ b% p( P
  s! r  W$ X0 _0 f& i  U$ T( k2 U9 e

5 r8 T5 Q- }' J我们对STM32H743片内Flash布局有了大致的了解,再去看看有关flash编程的介绍,了解相关规则。, Z1 ^( s4 `5 Y% a
0 G, j+ q: O; [: ]+ \

5 M* X- a3 Q1 q* V 3 (2).png 5 q# _+ p9 J' j7 T/ R9 R7 P$ E
9 H; C; d4 b6 ~$ P, c5 j- b
/ d1 R# ?; t/ R- H
从上面描述来看,在做Flash编程时要以256位即32字节为编程单位,或者说8个32位字为单位。硬件以256位做为一个Flash字,并进行读写ECC校验,以保障数据的安全可靠。  i7 O) ?1 ]' a' s
3 C- g5 Y+ m- X2 T
) ~2 t8 H% Z6 \: n4 T; V; p
那结合前面STM32H7用户的反馈,它现在每次是写40个字节的数据,既不是32字节也不是64字节,应该是在这个地方出了问题。4 _; w- j4 X( r6 @( S2 p) R2 b: G9 x
/ U+ z1 O) p8 s3 G3 o/ P. @0 [2 J
, u. b' K! U0 _  n
如果他使用下面Cube库函数实现的话,它默认每次就是写8个字的数据到指定的Flash空间。
0 C* W: s7 j( z' C8 G! ]0 B* s, |3 k" y. _# f) b6 j+ d
$ o4 E, X" [4 B6 G
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress,uint32_t DataAddress)
3 l" l( n+ K9 B. Y. `
8 R* P2 Q0 ?) c" @1 T$ {
8 d2 I# Q% D; ?% \: t0 ?5 f. c5 g
即基于该函数做flash编程时,若每次待写的数据多于8个字也没用。如果少于8个字,它会默认地从所给的内存起始地址连续读取8个字的数据。这个时候往往就很危险,很可能发生越界非法访问导致异常,或者读到一些未知数据写进去了。$ W( |1 w3 _4 j- k

, k6 m7 D& d7 x1 W+ D+ T. u8 M

. F2 N3 J$ {! a6 [如果我们不使用该函数,而是自己组织Flash编程函数,是否就可以按任意数据个数来写呢?显然也是不行的。每次改写Flash必须以256位为单位,如果少于256位的数据硬件就不会进行写动作的。
; D3 j& h! U/ ^, u
- p7 g% d2 D" @" `1 M8 i0 N
. ?* u/ J/ j9 D0 B; M
如果说像上面客户的40个字节数据怎么写呢?分两次,一次32字节,另一次8个字节实际数据外加其它24字节数据【比方24个0xff】凑成32字节再做编程,如下图所示。0 F* F9 N( o! d3 Y' c9 G4 |. {' x* g
4 r* M4 R7 \& ^! p. ~# f
4 K* e0 n- j. g, x$ N
4.png
1 }3 ~( A, Y1 I5 U3 y
9 j* k0 y. v! P; K

2 D" y0 g. j7 f" [. [, u2 p* {9 x3 ~  V另外,还有一个地方要注意,因为我们每次以256位Flash字为编程单元,那么在指定待改写的Flash区域的地址时一定要遵循32字节对齐,不然也是没法成功完成Flash编程的。比方说,结合上面实例,我们将FLASH编程的起始地址安排在0x080e0010或0x080e0030这些非32字节对齐的地方,是没法完成FLASH编程的。
% H  R; e4 a6 r4 n$ y. p! Y; z3 M9 J( n# u  k
3 r& E$ F1 }+ g9 A- B
最后,我们回过头来看看上面提到Cube库自带的那个flash编程函数的部分内容。
4 `: S$ Q% M0 c+ a' B
+ s' {5 U7 q) c% K- C
& _. g& e2 X" e5 K* M% Z% f0 Q9 l' Z
5.png 1 H4 b9 D/ k# J* G
7 ]6 m$ o* O- w: K* D

: k1 t9 U( V# J) l0 ]) H0 b红色方框内的代码就是实现8个字的赋值操作进而交给硬件完成flash内容的改写。两绿色方框内是两条汇编指令ISB和DSB。
' i6 \- y" x# t1 Z  D: ~1 w( I  {0 b4 @; E8 I" I

5 Y: y' ^6 T6 ]6 i5 mISB是指令同步隔离指令,ISB指令清除微处理器流水线的内容以确保ISB之前的所有指令得以彻底执行后才执行其后续指令。显然,ISB之后的指令需重新从内存或Cache提取。$ F, R" j/ p9 T  O6 M2 O2 n
9 r! B9 r: u+ C

" ~0 A) b+ O8 {DSB是数据同步隔离指令,在该指令执行完成之前,该指令后面的程序指令不会得到执行。而DSB指令的执行又是建立在该指令之前的所有内存访问操作的完成动作。换言之,DSB前面的内存访问操作未完成前,DSB及后续指令不会得以执行。8 d8 Y& H* P( f# n5 I# f# N
8 E6 [, a! y, V) Q) o$ P  Q
' Q. L0 k" v  C& h, D. S0 y
如果我们不使用库函数而是自行组织Flash编程代码的话,也可以参考下库函数的写法,尤其有些汇编指令的使用,可以参考借鉴。顺便提醒下,不同STM32系列的片内Flash编程模式或规则并不都一样,这里谈的是基于STM32H7系列的,不可一概而论地套用到其它系列。
( }4 C* A% ^6 h5 w0 M6 v/ V/ a$ N0 Z; L0 ~
( `+ F/ d, e: [( g5 l& a
好,今天的话题就聊到这里,圣诞快乐!
6 a8 N" B: w0 R7 S% R& N4 E8 ~+ k' t4 V; S  ?3 W
1.png
2.png
3.png
4.png
赞 收藏 评论0 发布时间:2019-12-24 12:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版