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

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

[复制链接]
yumeii 发布时间:2019-12-24 12:49
有人反馈在产品项目中使用STM32H743II芯片,在对片内flash进行编程时遇到点问题。9 d( d9 V* P: d# f0 z

' n( F$ `6 e; n. w2 b  v8 I

% o- H6 Y% S2 p- n他将片内的第一、二扇区存放用户应用程序,第七扇区用来存储网络应用相关的一些配置信息。他写Flash的过程及有关现象是这样的:* Q6 l1 ~  S+ w8 q
. l+ q! |5 C9 k9 Z* e1 r' V6 \
/ v7 H, ~& }* T# {) w. x
关中断->解锁flash->擦除扇区->写入数据->上锁flash->开中断,写入的数据总共40个字节。可是写完之后再去读时,发现只能读取前面32个字节的数据,在调试过程经常莫名其妙地触发硬错中断。这是怎么回事呢?* p9 \' ]+ V! u% c( w

2 M( [; D* y$ P( G* M. i0 y7 P/ T

: V1 w7 g5 Q! Y. S根据该STM32用户的反馈,基体情况就是对片内FLASH进行写操作不成功并衍生出相应问题。
8 }6 Z$ N+ Q* ?) ?  o+ S+ i$ K
: c$ C) X; v2 x. Y4 v; ~0 d

, E2 u3 j0 a% E, p2 O我们通过查看数据手册,不难得知STM32H743II片内FLASH为2MB,分为2个BANK.. M$ L7 m7 Y. _7 Y* U& e
' p' F6 G& ]0 F$ b! b3 ~) w

' r% ~8 J$ o2 ~1 D, h/ u 1 (2).png   z" o& W) ]9 C0 }2 S" }9 F2 F" j

3 F) I0 Q. V% `0 P

" H4 ]( ^- h  }" M2 C  `/ k5 Y片内FLASH布局如下:
, [+ E: T7 x# S' v0 r$ I8 U
/ l' w: q* s( }4 G" `: V3 c
- _& z& l3 r( v
1 (2).png
2 Y: h9 m7 Q# C' k5 u$ Q8 R  i! O  T5 v: [

. a/ @- y$ f" p: ]6 V" S, L我们对STM32H743片内Flash布局有了大致的了解,再去看看有关flash编程的介绍,了解相关规则。" e9 B" f9 J6 I

' c1 ]) m3 K# N1 Y% Z& z- }/ P) i% b
6 K5 `. D0 T5 Q2 f5 m  G( R4 }. `
3 (2).png
7 J3 i7 C% v( L: C; A- h& N
7 G8 n3 ]. Q7 B9 I$ O7 R
2 z( q, k5 a; ~) k) N3 J
从上面描述来看,在做Flash编程时要以256位即32字节为编程单位,或者说8个32位字为单位。硬件以256位做为一个Flash字,并进行读写ECC校验,以保障数据的安全可靠。
9 m& x, F: k6 l& M; f5 f0 D, `: s# q) @! q1 Y5 I8 t' k9 b

6 ]0 ]1 s' g. N7 N0 o% @那结合前面STM32H7用户的反馈,它现在每次是写40个字节的数据,既不是32字节也不是64字节,应该是在这个地方出了问题。5 @) U. ^- H% V7 `$ ?
0 x0 }9 n: F9 c6 c* K3 B4 p$ _

7 l& T! Q' K. s1 O如果他使用下面Cube库函数实现的话,它默认每次就是写8个字的数据到指定的Flash空间。
" \* k2 L1 a$ u& e' p. c$ W( O* o$ m* Q4 e) R. D
( J! A* g) ^) d; t/ c, N
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress,uint32_t DataAddress)
2 q3 x* p: e: V2 q- E1 i# W/ j7 |. N. B2 \% D

# f7 \  U; N. ?& U% f9 P: f即基于该函数做flash编程时,若每次待写的数据多于8个字也没用。如果少于8个字,它会默认地从所给的内存起始地址连续读取8个字的数据。这个时候往往就很危险,很可能发生越界非法访问导致异常,或者读到一些未知数据写进去了。7 g! I0 M# A: |4 C
5 z% j; T# y& F# n+ m# S5 b: V0 W; P
0 d) I: ]& A7 U6 r
如果我们不使用该函数,而是自己组织Flash编程函数,是否就可以按任意数据个数来写呢?显然也是不行的。每次改写Flash必须以256位为单位,如果少于256位的数据硬件就不会进行写动作的。. O$ ]/ V! D- M
) j" c7 v" w+ z

3 J: l' a& _  |2 S* I$ X- @如果说像上面客户的40个字节数据怎么写呢?分两次,一次32字节,另一次8个字节实际数据外加其它24字节数据【比方24个0xff】凑成32字节再做编程,如下图所示。
/ L4 w* q2 `) w; D1 u/ a! c
6 b' b9 a# S; D( ~9 y7 C; a( o

& y- r# B. F/ |& P& k. ~9 u 4.png
- z2 i$ c4 p9 e% A) \8 T% J; o5 f$ e

9 u% e: T& t* G( D' r+ V- `3 P另外,还有一个地方要注意,因为我们每次以256位Flash字为编程单元,那么在指定待改写的Flash区域的地址时一定要遵循32字节对齐,不然也是没法成功完成Flash编程的。比方说,结合上面实例,我们将FLASH编程的起始地址安排在0x080e0010或0x080e0030这些非32字节对齐的地方,是没法完成FLASH编程的。0 e8 U" o1 F- k: M! V5 G, b
' b, W, Q6 s# e1 j3 x0 n2 Z

. }' J5 B. ]6 B' d; T最后,我们回过头来看看上面提到Cube库自带的那个flash编程函数的部分内容。
% ]  ?, c" t2 A: }/ D7 ^- f$ t+ C1 _* y$ K* }# W

1 v( q8 W0 |/ G* C6 e- H- B 5.png
2 O# r3 x6 S& Z0 c1 Y/ g
. m: j: Q+ h5 s8 r! Q

" x( u6 F, ?/ D0 W& Q红色方框内的代码就是实现8个字的赋值操作进而交给硬件完成flash内容的改写。两绿色方框内是两条汇编指令ISB和DSB。# Y( e, E8 a& x2 r9 S& A* q( u
, M/ b& m% ~2 s2 \, U2 j

! L2 k7 g& X$ H& t; }ISB是指令同步隔离指令,ISB指令清除微处理器流水线的内容以确保ISB之前的所有指令得以彻底执行后才执行其后续指令。显然,ISB之后的指令需重新从内存或Cache提取。* d. s/ f* {" M

& n' I* i% F5 N! A- z2 ~
, e. {4 _5 v4 S
DSB是数据同步隔离指令,在该指令执行完成之前,该指令后面的程序指令不会得到执行。而DSB指令的执行又是建立在该指令之前的所有内存访问操作的完成动作。换言之,DSB前面的内存访问操作未完成前,DSB及后续指令不会得以执行。5 R. w" r7 q9 I+ _1 A! N9 }+ X5 E

, @; y3 z8 e7 b4 u" _: l: G' G( y0 ~

2 P) X8 r- Z: Z. Z0 v$ W/ V如果我们不使用库函数而是自行组织Flash编程代码的话,也可以参考下库函数的写法,尤其有些汇编指令的使用,可以参考借鉴。顺便提醒下,不同STM32系列的片内Flash编程模式或规则并不都一样,这里谈的是基于STM32H7系列的,不可一概而论地套用到其它系列。
6 W$ D  @) O& p/ u2 s$ J. @8 u# ]' i. O/ I; }

/ f! O0 w  l  g4 w好,今天的话题就聊到这里,圣诞快乐!
; |3 E% {* k. H" H7 G  P. R0 M, ]  f( `/ B
1.png
2.png
3.png
4.png
收藏 评论0 发布时间:2019-12-24 12:49

举报

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