一、前言- s$ v( l" |4 s3 M$ w9 j
有客户反馈,在使用 STM32H5 读取温度传感器校准值地址时,会进入 HardFault,而在其他系列芯片中读取这个参数时并没有此现象。在 NUCLEO-H563ZI 开发板上去复现此问题,发现只有开启 ICACHE 后才会复现,初步验证说明进入 HardFault 与 ICACHE 相关,如果直接关闭ICACHE 虽然可以解决进入 HardFault 的问题,但势必会影响代码执行的效率。所以,我们希望能找到一种更好的方式去处理此问题。% z- z3 Z8 V; b
; Q$ K" j9 T5 F G: d
二、问题分析, H- r) Y& Q$ V& S2 l: u
经 Datasheet 查询,两个温度传感器校准值 TS_CAL1 和 TS_CAL2 的地址分别为 0x08FF F814-0x08FF F815 和 0x08FF F818-0x08FF F819。7 l) s: w' ?- O, o2 K1 _
' L! [ o2 z- F$ a* @% ^
$ \0 K( K% M$ z: |" |
# {6 f& y L) [( `+ `, c4 f/ [根据下表,可以知道 TS_CAL1 和 TS_CAL2 是属于 Read-only 区域的,而 Read-only 区域是通过 AHB system bus 访问的。
0 E1 n% |+ O! w7 \8 N) [# c+ y4 p" D* H4 u4 q/ V; y
- p1 {0 g( c( Q. {
+ s' O8 s1 v, K- L% O
7 {+ B+ U; ~3 W3 [& W! H
根据参考手册的描述,所有的 AHB memory 默认都是 cacheable 的,对于无法实现缓存的区域(OTP、RO、data area),必须使用 MPU 来禁用本地缓存。: m; H3 I z) i# q7 _
. [: s0 ~5 E- e. q4 F
) _; }0 a0 e* [* m" A0 E: p5 |
+ a- c! o. Z, A3 _也就是说,不仅是 TS_CAL1 和 TS_CAL2,其实整个 OTP、RO(Table 39)、data area区域的访问都无法经过 Cache,需要使用 MPU 将其配置为 none-cacheable 属性。4 ]5 V; K8 p$ N' g0 A
0 i0 i: q! |* d1 |0 F0 Q0 O4 {
既然知道了问题所在,那剩下的问题就是确定 OPT、RO、data area 各个区域的地址,data area 是由用户选项字节配置的可进行 100k 次擦除的区域,用于存储用户掉电不丢失的数据,需要根据实际的配置去设置 MPU 区域。剩下的就是 OPT 和 RO 区域,在 STM32H563 中,分别有 2K byte。
( Z: l# Y: M/ C/ \& ^; D, h: H
7 K1 W4 }8 f l% b' u+ S
/ M5 _) Y, e& e3 b; U
! y( h4 E4 v. z7 r" E! k* e7 I' i- c
OTP 的地址为[0x08FF F000-0x08FF F7FF]和 RO 的地址为[0x08FF F800-0x08FF FFFF],两个地址其实是连续的。+ z9 M7 T& @( g, F
/ _# y: P; z r6 o/ x2 g/ D
5 G7 Y9 n3 H* O9 N$ i# [/ W W/ ~3 w5 N& M9 s
三、解决方法 Z' l* K- Z! T6 o
经上述分析后,我们只需要把[0x08FF F000-0x08FF FFFF]这段地址区域设置为 none cacheable,通过 CubeMX 进行配置。
, l1 ]/ E b) e- a2 e) f; x! M0 }+ W% U
. A7 C6 o: ?: N: d( _1 O9 s
, A& m. E( ]. @ l3 o% }- void MPU_Config(void)
% P. e% N& q5 f" O - {, ?, `# k. C( A3 [% G: G( _
- MPU_Region_InitTypeDef MPU_InitStruct = {0};
$ P' o# c( ~8 a# p - MPU_Attributes_InitTypeDef MPU_AttributesInit = {0};
: D) e* O C! g* P4 J0 V$ O - 9 m- n9 a; [ F& m0 i
0 V5 v/ v+ [: @, n+ n3 s( q- /* Disables the MPU */
& \- e% \* g) v - HAL_MPU_Disable();' Q! k9 `; D# G+ ]0 `3 D
! ^4 Y. Q% W$ F2 E# A
3 m) y6 t+ l, ?7 s9 e- /** Initializes and configures the Region and the memory to be protected* X% o. G7 P9 Z" q
- */2 }6 W3 L( \: |7 R: N1 [
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;
( h) @4 m+ m/ ?5 b+ j' } - MPU_InitStruct.Number = MPU_REGION_NUMBER0;: i6 N7 W* m7 i- j* X
- MPU_InitStruct.BaseAddress = 0x08FFF000;* C- \& H2 {' y: `& C
- MPU_InitStruct.LimitAddress = 0x08FFFFFF;
$ W [# L0 C+ h! t+ Y - MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
/ Y9 T$ q# w3 @0 a8 m# q8 ?) H+ J - MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RO;
4 a) _5 J$ Y) I5 f9 p* {( W) p% C - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
( G5 R$ Q1 r* f4 q3 } - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;' |& a3 I; B5 p$ `8 q/ F5 g
- + y1 m( O: g4 ?
- # m9 P1 M5 b0 C; i' C
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
9 w0 ?) h9 |. j; A1 J/ K% ` - MPU_AttributesInit.Number = MPU_REGION_NUMBER0;+ W4 {+ H7 U6 q/ t
- MPU_AttributesInit.Attributes = INNER_OUTER (MPU_DEVICE_nGnRnE | MPU_NOT_CACHEABLE5 D1 [/ G/ `$ _$ q' w6 |
- | MPU_TRANSIENT | MPU_NO_ALLOCATE);1 R3 |. q3 T' p! I
2 Z0 O6 V& P, l, U) p4 @( u
6 s* J: v3 W7 F- HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
& l' Q$ @' |; v" k% q - /* Enables the MPU */
- s5 L- d( O. L! N$ Q" U1 {7 k# q1 [ - HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);$ m. J; Y* P/ a
- }
复制代码 ; d# F: y# j% V8 X
经 MPU 配置 OTP 和 RO 的内存访问属性后,就可以正常去读取温度传感器校准值了,同时属于这两个区域的其他值,如 UID、Flash Size、Package 等信息也能正常读取了。
! r: v! \. T) r. l+ e8 E# N- G2 w8 k9 `, r Y5 c( H$ G
- uint16_t TS_CAL1_Val,TS_CAL2_Val;9 O1 c/ I; b2 q, k! ^* x% S! S
' H. Y! k! c( }" L$ k) M$ ~
# B; y% X5 y" U8 d# f- J% n- uint16_t *TS_CAL1 = (uint16_t *)0x08fff814;4 h2 M7 _' M9 o7 ]0 ]3 b+ W5 H
- uint16_t *TS_CAL2 = (uint16_t *)0x08fff818;% B" O- h/ c+ v Z0 |/ B4 `2 K- N
- TS_CAL1_Val = *TS_CAL1;8 a0 ^" w7 g4 ^5 Q) K
- TS_CAL2_Val = *TS_CAL2;
复制代码 4 G% f$ e- Q6 m
四、总结
& p A* Y1 F$ M1 S0 c, q& V8 Q温度传感器校准值及 UID 等一些信息在 H5 中属于只读区域,而这个区域在 AHB 访问时,默认内存属性为 cacheable,需要通过 MPU 把这些区域设置为 none-cacheable,才能正常访问。每个系列的芯片架构都或多或少有差别,当按以往经验操作不能实现功能时,不妨对照相应芯片的数据手册、参考手册、应用笔记、甚至勘误手册,也许就能发现问题所在。% H3 h6 S; O7 C# U w/ _1 m: R. H9 U# c
1 x+ h* Y0 t# [# K9 O- k5 X% o' i4 V# ~( H& A3 f2 G9 t
转载自: STM32
5 D. Z) }9 v, k* L X如有侵权请联系删除6 ?. g: P4 f) _' y
) J- h0 p/ A+ W( X( t. l
3 C5 T( w, ^, R; G: H |
一键三连,学习起来