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

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

[复制链接]
yumeii 发布时间:2019-12-24 12:49
有人反馈在产品项目中使用STM32H743II芯片,在对片内flash进行编程时遇到点问题。
; O2 s: q- J, d3 y& v- ]
" ^6 o' N: ^4 O" R' L9 K/ W4 Q
3 `+ d9 R" g3 H
他将片内的第一、二扇区存放用户应用程序,第七扇区用来存储网络应用相关的一些配置信息。他写Flash的过程及有关现象是这样的:; q$ I# x$ ~5 _) p6 v
1 i/ G# B1 V  Z6 B. L6 h

4 |& }& W. Y" t+ x; X; `关中断->解锁flash->擦除扇区->写入数据->上锁flash->开中断,写入的数据总共40个字节。可是写完之后再去读时,发现只能读取前面32个字节的数据,在调试过程经常莫名其妙地触发硬错中断。这是怎么回事呢?/ u6 v4 g+ {. k0 H) }+ Z4 V& e

7 e& ~2 l  S+ k9 U

2 `6 N0 S3 n0 [根据该STM32用户的反馈,基体情况就是对片内FLASH进行写操作不成功并衍生出相应问题。
3 m. }% A- w/ x% }0 B$ ]; V" [* S6 v; v. i2 W3 @  C. n$ n

+ a* ^* [! N& }& D* J) W) r我们通过查看数据手册,不难得知STM32H743II片内FLASH为2MB,分为2个BANK.
6 e$ E. J, S) [* A6 t6 |2 w% z8 X: Z( I7 C) |+ i) Z# K; C
0 y: c' [# x6 d- J2 \5 b. z
1 (2).png
6 s% s: X) k# `1 r+ U5 a  _, g7 D6 K7 m  A6 z5 |! W: s$ d
- M$ `+ p* _( `1 ?. W: I8 }4 t" D
片内FLASH布局如下:) w6 s9 x2 Z. q) D8 [

" }8 r- ^( C- U1 I9 _$ a# m
+ a* F: c2 D9 {- H, `0 K3 \! l' |
1 (2).png
0 ?) a" i, N  f% N3 p0 O- c  U& ~) z$ q

* C" ^+ S8 K$ W0 d9 J我们对STM32H743片内Flash布局有了大致的了解,再去看看有关flash编程的介绍,了解相关规则。
- n7 x' T, E, E$ R1 _8 H6 @9 N. h1 \: w! j' R6 `+ P  t
5 v4 _) b9 M, \" V, }+ y8 _
3 (2).png & A; t9 b' o! H
- l8 O' U7 R" a

5 F8 {, h, [1 _: `9 j从上面描述来看,在做Flash编程时要以256位即32字节为编程单位,或者说8个32位字为单位。硬件以256位做为一个Flash字,并进行读写ECC校验,以保障数据的安全可靠。% z$ b" Z$ i% P& }" T( l
1 e4 o) M- v: e

$ C( S2 r0 i; j4 X那结合前面STM32H7用户的反馈,它现在每次是写40个字节的数据,既不是32字节也不是64字节,应该是在这个地方出了问题。
+ @# O, j; v2 i1 o9 u% E8 e9 _4 S4 G1 A! v9 Z% B/ t. j0 _8 F+ C6 F

9 v4 i8 A# c; d1 |& a1 }& u& s' c8 _如果他使用下面Cube库函数实现的话,它默认每次就是写8个字的数据到指定的Flash空间。! a! T2 l/ S* G! ]! U

* M8 I& T8 Q' h+ p! X* H

  i2 a9 v" x' |6 l* ]3 LHAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress,uint32_t DataAddress)
6 |4 E# L) N$ D/ @+ E; W+ z& D7 P& u/ h$ F

" m: s7 G  b4 Y! y# Q/ `即基于该函数做flash编程时,若每次待写的数据多于8个字也没用。如果少于8个字,它会默认地从所给的内存起始地址连续读取8个字的数据。这个时候往往就很危险,很可能发生越界非法访问导致异常,或者读到一些未知数据写进去了。; d0 A( N% i0 f2 W! U% P* u
& r/ ?6 V0 u9 p
+ c' g  e( s+ D5 n% c
如果我们不使用该函数,而是自己组织Flash编程函数,是否就可以按任意数据个数来写呢?显然也是不行的。每次改写Flash必须以256位为单位,如果少于256位的数据硬件就不会进行写动作的。- _* u  }7 ~9 y0 y! L) Q: }6 c9 K
1 q1 {3 ?0 `3 ~. W
3 Y( _% m' G, b, c
如果说像上面客户的40个字节数据怎么写呢?分两次,一次32字节,另一次8个字节实际数据外加其它24字节数据【比方24个0xff】凑成32字节再做编程,如下图所示。
& L+ I# A) ^$ `( I* O: @6 i$ N
' h, D( d0 V9 n  [$ N6 |: X
1 K) D, ^% [& D8 }, T/ J+ t  T
4.png
% W# E! A& j' b# g7 o+ Z( w/ [- e$ `6 ^

( L) t( [* O7 Q! K! o( T: @2 }" V另外,还有一个地方要注意,因为我们每次以256位Flash字为编程单元,那么在指定待改写的Flash区域的地址时一定要遵循32字节对齐,不然也是没法成功完成Flash编程的。比方说,结合上面实例,我们将FLASH编程的起始地址安排在0x080e0010或0x080e0030这些非32字节对齐的地方,是没法完成FLASH编程的。' t3 p# g3 Z6 Z6 y9 {# i

& M; f% A5 Q9 g

; J7 I7 n! j! s+ b7 L9 h9 k最后,我们回过头来看看上面提到Cube库自带的那个flash编程函数的部分内容。
' O" [* z( F: e  T1 E0 j5 y
* l4 d% U" L- c0 |' @8 i) \* X, A

% K: p: o" S7 |: b7 u 5.png
  J3 G( _, F7 t5 _! A! Z5 i. u% p- k
8 V0 P4 S- S2 w8 }
红色方框内的代码就是实现8个字的赋值操作进而交给硬件完成flash内容的改写。两绿色方框内是两条汇编指令ISB和DSB。
' @% s8 C+ a0 j' {3 M& C) }+ k+ n7 g' l* Q# O
1 g3 \( r/ _3 s/ T5 E, U
ISB是指令同步隔离指令,ISB指令清除微处理器流水线的内容以确保ISB之前的所有指令得以彻底执行后才执行其后续指令。显然,ISB之后的指令需重新从内存或Cache提取。( k$ j" u  F, ^/ W8 E8 ^

/ w! w  k% Z2 |, s, f. H
) @# u$ o- u$ _! B8 u
DSB是数据同步隔离指令,在该指令执行完成之前,该指令后面的程序指令不会得到执行。而DSB指令的执行又是建立在该指令之前的所有内存访问操作的完成动作。换言之,DSB前面的内存访问操作未完成前,DSB及后续指令不会得以执行。
2 e+ ~, J  u, u  U, ~
; @+ v! a3 E" }

# A2 A' p! ]: F  v如果我们不使用库函数而是自行组织Flash编程代码的话,也可以参考下库函数的写法,尤其有些汇编指令的使用,可以参考借鉴。顺便提醒下,不同STM32系列的片内Flash编程模式或规则并不都一样,这里谈的是基于STM32H7系列的,不可一概而论地套用到其它系列。
9 Z- N9 ~% O. i; Q! y) k, I* f, ?# r- L* K* B' F% A

2 p( b$ L6 q* I好,今天的话题就聊到这里,圣诞快乐!
" h5 |6 r; \# {, H9 E0 y
/ I0 B8 w) W# q% u9 _6 D- ]
1.png
2.png
3.png
4.png
收藏 评论0 发布时间:2019-12-24 12:49

举报

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