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

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

[复制链接]
yumeii 发布时间:2019-12-24 12:49
有人反馈在产品项目中使用STM32H743II芯片,在对片内flash进行编程时遇到点问题。' y9 t3 Z+ @; X% e- E1 d7 g
$ s, y( D7 L1 h

' I1 Z3 V/ a$ b/ m+ L/ l( J他将片内的第一、二扇区存放用户应用程序,第七扇区用来存储网络应用相关的一些配置信息。他写Flash的过程及有关现象是这样的:7 r; B9 g# J4 u5 C/ j& I6 P/ |
  `. _7 [0 R1 U$ p( ^4 X

3 z# [4 K2 S8 J. y$ s9 B8 B关中断->解锁flash->擦除扇区->写入数据->上锁flash->开中断,写入的数据总共40个字节。可是写完之后再去读时,发现只能读取前面32个字节的数据,在调试过程经常莫名其妙地触发硬错中断。这是怎么回事呢?" L3 g; z( k; A( m- j( w* a  I/ M
0 \* N% U- n0 m- S0 g8 z7 G* O

* Y; c7 K) G5 M5 R" q* S0 F2 |根据该STM32用户的反馈,基体情况就是对片内FLASH进行写操作不成功并衍生出相应问题。9 y8 T; x1 B) ^* Q, v# `9 Z$ `! M& Q
( F7 C( `. t5 [$ r) k, C, |0 v
! Z4 p- L( k+ A! p
我们通过查看数据手册,不难得知STM32H743II片内FLASH为2MB,分为2个BANK.( ?' }, }. a6 x8 S9 s9 L3 e/ [

' q% P9 ]! l' _" A: J
1 B& q9 R! U: _- A3 ^& G7 k
1 (2).png ; C- Z6 v( ^1 l, a2 q$ Q
9 s% k) x/ P% p8 [

8 [  f; g7 i( @. t片内FLASH布局如下:
6 G' R& w( Q) s+ B1 Y
/ F2 X& H  g4 d6 N- A  Q4 W

+ E! P. R: f9 l 1 (2).png
* w* W/ M8 r9 I/ l
2 ^# Q3 P7 t  g' k  C7 z4 N2 b% `% I
) @- p; E) \7 Q! I
我们对STM32H743片内Flash布局有了大致的了解,再去看看有关flash编程的介绍,了解相关规则。
, R& u* j' N( p9 i- I9 k3 z) S2 L, C9 N- W* i* l/ {. _) q

! t- s+ g0 K  b* o9 s' X- @" c% w" h 3 (2).png 9 v. q! D/ Y- l. o- S6 M* U0 w5 q
8 r4 o5 d3 K. h, x- R
- K2 i/ x" w4 _/ ~  X
从上面描述来看,在做Flash编程时要以256位即32字节为编程单位,或者说8个32位字为单位。硬件以256位做为一个Flash字,并进行读写ECC校验,以保障数据的安全可靠。" }$ P( q/ K2 K

- k5 M0 M: Y5 j; f0 P$ _

+ Y  P( u" f/ n那结合前面STM32H7用户的反馈,它现在每次是写40个字节的数据,既不是32字节也不是64字节,应该是在这个地方出了问题。5 v/ I2 n! o3 ~. w: q- ~! Y- v* T8 ~+ c

. ^+ M" Q4 b" T& K- Z+ T
( f& |3 F  M; N: P! Z2 F+ l5 g
如果他使用下面Cube库函数实现的话,它默认每次就是写8个字的数据到指定的Flash空间。9 m4 S6 \* L+ w# @# T: m

8 U4 r$ L% {, ]

) `) ]) `. O, V$ T& @. wHAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress,uint32_t DataAddress)
0 U  H& O2 K/ j. |5 t1 z, Q
) Z3 M+ C' m6 V

3 P$ z7 N+ I( R即基于该函数做flash编程时,若每次待写的数据多于8个字也没用。如果少于8个字,它会默认地从所给的内存起始地址连续读取8个字的数据。这个时候往往就很危险,很可能发生越界非法访问导致异常,或者读到一些未知数据写进去了。+ R' E6 a$ @" H; y
. M1 n5 v' o: M; A0 s* A

, q' O4 ]: l$ J, t' l) J) E. [如果我们不使用该函数,而是自己组织Flash编程函数,是否就可以按任意数据个数来写呢?显然也是不行的。每次改写Flash必须以256位为单位,如果少于256位的数据硬件就不会进行写动作的。
5 o0 c3 ~' k% S7 j9 y: u* @
* E  ~0 r" S' e" u
' d2 ]2 W% H& W/ z
如果说像上面客户的40个字节数据怎么写呢?分两次,一次32字节,另一次8个字节实际数据外加其它24字节数据【比方24个0xff】凑成32字节再做编程,如下图所示。; w% J0 j7 O3 S/ I6 V7 H

* a3 R) b  }9 ~4 D5 B) L

" E& N$ E7 L# |# A2 f4 t# Q 4.png
3 Z9 X. _. _& t) _& O; d' i0 `
& W" a0 D; T; W  _# ~. s! t
8 ^% i- _' u5 J8 Q. g
另外,还有一个地方要注意,因为我们每次以256位Flash字为编程单元,那么在指定待改写的Flash区域的地址时一定要遵循32字节对齐,不然也是没法成功完成Flash编程的。比方说,结合上面实例,我们将FLASH编程的起始地址安排在0x080e0010或0x080e0030这些非32字节对齐的地方,是没法完成FLASH编程的。  E' [% w: B6 f9 ~; f; X
( l$ ]/ r- ~7 t0 x4 v
! R; d8 }  l. N6 O9 k$ e  q
最后,我们回过头来看看上面提到Cube库自带的那个flash编程函数的部分内容。" b! v. e+ s0 X8 u5 |. g1 R3 m
% F, L2 h$ q% b. R

2 k! @/ X5 [3 e- e0 O 5.png 7 Z# u& o6 K( W" y
; z2 z$ G% u" e6 {6 x
4 [+ b0 W  X% Y6 ^
红色方框内的代码就是实现8个字的赋值操作进而交给硬件完成flash内容的改写。两绿色方框内是两条汇编指令ISB和DSB。" O4 y2 ^2 l# @$ b
; a. [0 ~5 |/ w3 v
6 q! U. b6 o4 v4 l) {
ISB是指令同步隔离指令,ISB指令清除微处理器流水线的内容以确保ISB之前的所有指令得以彻底执行后才执行其后续指令。显然,ISB之后的指令需重新从内存或Cache提取。4 `3 O% U4 P1 D+ F& R# u
1 |' d" \! W+ q) g" r
) u9 [& {2 p: o" a  y) V0 e
DSB是数据同步隔离指令,在该指令执行完成之前,该指令后面的程序指令不会得到执行。而DSB指令的执行又是建立在该指令之前的所有内存访问操作的完成动作。换言之,DSB前面的内存访问操作未完成前,DSB及后续指令不会得以执行。" }; U# @" X% W; K, A- f0 X

7 X; \* M" A/ h4 x7 ~( ]

1 f) B" g/ s; ~2 s; l  |2 J如果我们不使用库函数而是自行组织Flash编程代码的话,也可以参考下库函数的写法,尤其有些汇编指令的使用,可以参考借鉴。顺便提醒下,不同STM32系列的片内Flash编程模式或规则并不都一样,这里谈的是基于STM32H7系列的,不可一概而论地套用到其它系列。
( |$ v% a  m0 G& H6 d
8 g1 t9 S& r2 A
) i/ ], g) |9 ^* q, N8 C# {& u' I
好,今天的话题就聊到这里,圣诞快乐!
( a: l; y. }0 W' a( l; l/ W* T( U+ }
5 T4 a! C5 w' F/ M4 G
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 手机版