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

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

[复制链接]
yumeii 发布时间:2019-12-24 12:49
有人反馈在产品项目中使用STM32H743II芯片,在对片内flash进行编程时遇到点问题。
2 V2 M, N) \& \, v) h, Y3 k6 F  P5 C1 |; W9 f$ W. [
+ K  }" Y; W  F+ r, `, \' @2 e
他将片内的第一、二扇区存放用户应用程序,第七扇区用来存储网络应用相关的一些配置信息。他写Flash的过程及有关现象是这样的:- H. X! I% I% i1 }! o
! @; G; v& [- I" ~  T7 ^9 C
# B4 A* g0 F3 I: x
关中断->解锁flash->擦除扇区->写入数据->上锁flash->开中断,写入的数据总共40个字节。可是写完之后再去读时,发现只能读取前面32个字节的数据,在调试过程经常莫名其妙地触发硬错中断。这是怎么回事呢?% J. z3 x, _& D1 w7 h

) |4 f0 P4 D% C& O/ Z& u3 T
1 `" {  `/ B$ s- f! ^1 s
根据该STM32用户的反馈,基体情况就是对片内FLASH进行写操作不成功并衍生出相应问题。) e* t" W4 a' g( s; M6 U! T1 L" n
+ S% l# j: O. _) v0 i

0 r0 O3 `- t/ T* K  K我们通过查看数据手册,不难得知STM32H743II片内FLASH为2MB,分为2个BANK.
1 G6 p4 e0 j; t5 n" p' X/ Q
+ b& ~# `! G2 ?* w

- C; N  ^3 i/ I$ X2 |: K1 L& s 1 (2).png 7 p. H( p3 |2 ~5 V( S

: X0 o3 g) t" n/ y/ p: y6 P/ X
; I+ {% {% e5 n9 B7 G
片内FLASH布局如下:
8 x; t: o  P6 K% n% c1 O
$ n. ]! }% R- J5 B

8 ]9 X) J) J; u% v5 |! x 1 (2).png
2 w9 S. N% F# A" _) v
/ p1 @# e+ G# ~( q( `5 J" x) P3 L( I& K- a

  Z7 ?( m  E& L6 m* j我们对STM32H743片内Flash布局有了大致的了解,再去看看有关flash编程的介绍,了解相关规则。
7 ^! H( \# S) H+ N  T$ b. `5 O1 y4 z6 b. y* c! U$ [8 `* R  w' J

/ g+ T) r# r3 r  ^5 f  |1 M 3 (2).png 6 t# U# R0 T/ I4 @+ F7 }, Y
; e8 A6 n) E& _7 u0 K0 {

4 M" ~# ?* L9 I0 Q* U0 Q从上面描述来看,在做Flash编程时要以256位即32字节为编程单位,或者说8个32位字为单位。硬件以256位做为一个Flash字,并进行读写ECC校验,以保障数据的安全可靠。* x& K. {- E; b% Z: v% @- }

% X  {0 |( S4 g8 x0 f7 d
8 X) L. d7 b& x& Q2 I- v
那结合前面STM32H7用户的反馈,它现在每次是写40个字节的数据,既不是32字节也不是64字节,应该是在这个地方出了问题。5 P! _! }  }4 V7 i9 E7 N

1 j2 I$ v. O$ I7 i: f; T( n

& ?9 x/ [; q  g$ g# K如果他使用下面Cube库函数实现的话,它默认每次就是写8个字的数据到指定的Flash空间。
: \9 G+ D& u0 v$ D% j. A/ P/ i+ \
& ^- w/ O2 g6 |4 K/ B

8 \0 P8 u7 }$ e. e8 N9 Z$ \- {( n" W7 HHAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress,uint32_t DataAddress), e2 u1 K" q$ l6 b. B8 l

/ w: O/ r9 Y0 _: S
; V0 U) G% ~' y* ~
即基于该函数做flash编程时,若每次待写的数据多于8个字也没用。如果少于8个字,它会默认地从所给的内存起始地址连续读取8个字的数据。这个时候往往就很危险,很可能发生越界非法访问导致异常,或者读到一些未知数据写进去了。
: N! m9 w& [3 y6 Z3 b& d
: z- g+ t+ ]( O# D4 ~

3 W( _; o, r. A; e; H如果我们不使用该函数,而是自己组织Flash编程函数,是否就可以按任意数据个数来写呢?显然也是不行的。每次改写Flash必须以256位为单位,如果少于256位的数据硬件就不会进行写动作的。7 d0 e; |+ c8 `
" B1 b( n) H$ C8 d9 y3 L( o5 X
* ?% C, x" t$ G
如果说像上面客户的40个字节数据怎么写呢?分两次,一次32字节,另一次8个字节实际数据外加其它24字节数据【比方24个0xff】凑成32字节再做编程,如下图所示。6 b& ]. Z* A5 ~' S9 S& d
& o$ O3 m) G; u# N6 D+ f) f
9 A! a7 r, a' n
4.png ( V2 s6 L- o3 s+ ?" Z0 Q
. S. D+ w' W- X- P# q

7 ~/ a. K3 x6 ^$ Q2 \另外,还有一个地方要注意,因为我们每次以256位Flash字为编程单元,那么在指定待改写的Flash区域的地址时一定要遵循32字节对齐,不然也是没法成功完成Flash编程的。比方说,结合上面实例,我们将FLASH编程的起始地址安排在0x080e0010或0x080e0030这些非32字节对齐的地方,是没法完成FLASH编程的。  H7 a& `7 M, E( ~5 u3 J( M$ @
3 j+ d; \7 O' S) @- u
) }3 ?. \, n5 l5 s, ~: G" Q$ E
最后,我们回过头来看看上面提到Cube库自带的那个flash编程函数的部分内容。: b  M8 J2 r, Y( z6 ~$ {

( u) J! k" T. y) O' [. B# u+ y
0 F# A- |1 r* \
5.png # u1 B. \) T$ \- x6 l( d' T
" V" D; M/ K1 W& e8 g+ W
2 i, E1 @$ E# G+ j
红色方框内的代码就是实现8个字的赋值操作进而交给硬件完成flash内容的改写。两绿色方框内是两条汇编指令ISB和DSB。4 P/ c2 W8 X" G( w7 i

, c2 t  L- B+ l/ ~% x( j
2 D4 i+ Z. P* L+ a6 b
ISB是指令同步隔离指令,ISB指令清除微处理器流水线的内容以确保ISB之前的所有指令得以彻底执行后才执行其后续指令。显然,ISB之后的指令需重新从内存或Cache提取。7 @( B9 }9 R5 @& F' S' Z/ Y2 e/ O
3 e* _7 \2 ]4 x- Y: V" Y
$ `( R$ V2 i  Y. k9 \# F# S  h
DSB是数据同步隔离指令,在该指令执行完成之前,该指令后面的程序指令不会得到执行。而DSB指令的执行又是建立在该指令之前的所有内存访问操作的完成动作。换言之,DSB前面的内存访问操作未完成前,DSB及后续指令不会得以执行。6 i- S! w! d# \, h$ Z2 n% J
- p/ V' A* R" O7 B% D2 M

+ g9 I* R9 x% m4 m* L& U7 B如果我们不使用库函数而是自行组织Flash编程代码的话,也可以参考下库函数的写法,尤其有些汇编指令的使用,可以参考借鉴。顺便提醒下,不同STM32系列的片内Flash编程模式或规则并不都一样,这里谈的是基于STM32H7系列的,不可一概而论地套用到其它系列。
  m$ K6 D. A1 Y7 x5 K/ \* c9 D4 u6 l4 B5 p, a9 Q% j

9 Z( D5 o& H# w4 B* s4 R好,今天的话题就聊到这里,圣诞快乐!
  w5 Z' O* l; {: X/ T
+ [' N! G" G. V
1.png
2.png
3.png
4.png
收藏 评论0 发布时间:2019-12-24 12:49

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版