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

STM32F0xx_EEPROM_Emulation BUG的修正

[复制链接]
wenyangzeng 发布时间:2018-10-27 19:18
本帖最后由 wenyangzeng 于 2018-10-28 11:33 编辑
0 _# W: }) \* _5 w- ?/ \
7 a( Y- A7 e- M- Z$ E- f/ q               STM32F0xx_EEPROM_Emulation BUG的修正9 i' ~0 ?( K; l; }
  |+ M3 f& d' L) T% i
     应用中需要使用STM32F051C6T6的FLASH仿真EEPROM,以便在断电时保存部分数据。在ST官网下载固件库STM32F0xx_EEPROM_Emulation。http://www.stmcu.com.cn/Designr ... F&lang=EN&ver=1.0.0    7 z$ V0 o2 G3 s& X& O
5 L% q$ h: G) \/ W
       首先在演示代码中编译下载原代码进行评估、验证。
) Q4 S8 o1 k+ i; x/ z      演示代码主函数中先对VarDataTab[0]-VarDataTab[2]写入,然后再读出:
/ q* ~( ~; J. A/ n1 Y# k
  1. for (VarValue = 1; VarValue <= 0x64; VarValue++)
    1 p2 h5 }, q7 ?+ P. D4 C
  2.   {
    7 j  {, n1 ?% \# }
  3.     EE_WriteVariable(VirtAddVarTab[0], VarValue);, c* d1 _7 ~' o3 T3 o# F- ]
  4.   }
    ) H0 _3 p6 S) O
  5. 再读出。( F$ K0 t0 i( J) j5 A
  6. . w$ P+ f& Y1 `" _: f
  7.   EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
    + ]8 `  N5 B$ ~6 Q
  8. 9 n$ z* L5 w6 G, E3 i: l, k

  9. / G/ ?: N- }" j) X1 ]' j9 j" e
  10.   for (VarValue = 1; VarValue <= 0xC8; VarValue++): ]0 h' e/ a) n+ @% f$ a1 \
  11.   {% E. B% g1 n- z* q& k# v* J( u% i
  12.     EE_WriteVariable(VirtAddVarTab[1], VarValue);. m- n; ~5 X! w! c% t- m$ r
  13.   }2 p5 x5 q$ x0 c- @( j9 [
  14.   EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
    7 U- C2 ?% j* [& N
  15.   EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
    . x  l! {* k6 s: l
  16.   for (VarValue = 1; VarValue <= 0x1C2; VarValue++)
    1 I, k2 H# l3 y: R
  17.   {
    9 v: B# p. o& _/ C/ z$ U
  18.     EE_WriteVariable(VirtAddVarTab[2], VarValue);6 ]3 m% B6 Y- B9 y4 q$ ]
  19.   }* ^6 G0 {9 `& b0 ^  k4 l
  20.   /* read the last stored variables data*/3 {2 {$ t: e( H) J
  21.   EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);' N) j! n8 p' v
  22.   EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
    " d; g4 q4 z1 Z  j! w
  23.   EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]);
复制代码
     编译下载后运行,检查VarDataTab[0]-VarDataTab[2]的内容,与写入数据一致。本以为一切正常,就移植到实际项目中。
2 C" k. u( }9 \# \     STM32F051C6T6的Flash长度为32K,仿真EEPROM需要使用2页,占用第8扇区和第9扇区,首址是0x08002000,每页长为0x400,(0X08002000到0x080027ff)。不料移植运行后,发现断电后重启,读出的数据均为空数据。- U; E3 U7 u$ b% ?5 t, ]' J+ P9 I' G
      用STM32 ST-LINK Utility工具读0x08002000,发现数据已经正确写入了。  ~) ?9 O* M6 c! s7 a% o

  k) s5 i" q5 ~# c! ^' J 无标题.png
- x6 k' C8 C3 @  S4 B: C
: N: M0 U) Y: ]0 h    判断问题出在读数据操作。" Q! m' P* @5 u) z

' E/ {( n! w2 e2 y' N+ i( `  查阅STM32F0xx_EEPROM_Emulation演示代码eeprom.h的描述:
: O( N9 @1 ^1 U, f
  1. /* Exported constants --------------------------------------------------------*/, E1 Q0 e8 h2 x" ]
  2. /* Define the size of the sectors to be used */
    9 A! L# T9 X" z3 Z% u
  3. #define PAGE_SIZE             ((uint32_t)0x0400)  /* Page size = 1KByte */8 L% `* [; f+ J( V! v

  4. 1 u) U* r" y, t+ i
  5. /* EEPROM start address in Flash */+ S2 `" l1 {' h% j; D
  6. #define EEPROM_START_ADDRESS ((uint32_t)0x08002000)/* EEPROM emulation start address:
    * P& E9 A, w% Q# u
  7.                                                         from sector2, after 8KByte of used
    4 \. E7 z7 c$ w$ q$ I) p0 K
  8.                                                         Flash memory */
    0 F5 M- g0 q7 y; z5 V8 E* P, F+ Q3 Z
  9. 4 r* X* c, ?/ w/ E- K1 q; e
  10. /* Pages 0 and 1 base and end addresses */3 d9 {' }& L7 P  ?( G! s8 i' X9 s
  11. #define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))4 I$ W; |1 F- _8 u
  12. #define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))8 B: k3 t4 E% C9 p

  13. * j: [- L( {8 ~/ ~: s0 C, g
  14. #define PAGE1_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0400))8 J! i) p" b1 ~8 O7 p% X5 O# c7 j
  15. #define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))' F! {+ t; Y. R% v
  16. " c- p  ?; P% j, u( a' \' [
  17. /* Used Flash pages for EEPROM emulation */
    9 k0 |( c$ S1 Z& u# q
  18. #define PAGE0                 ((uint16_t)0x0000)
    4 }4 B: Q( U; \- G
  19. #define PAGE1                 ((uint16_t)0x0001)4 z# U9 M0 J5 n) U

  20. 9 B0 A  s7 j: Q8 p. Q; l* o0 z
  21. /* No valid page define */) Y! K0 s* N4 l( q* T* m
  22. #define NO_VALID_PAGE         ((uint16_t)0x00AB)
    * [* u' f4 N& n4 r4 v; B! j

  23. / {3 H: B) H) \* H4 q) C, h
  24. /* Page status definitions */7 R: o! h6 l& w# O. T; P# q/ e# m
  25. #define ERASED                ((uint16_t)0xFFFF)     /* Page is empty */
    6 G& z4 b& R! N3 Y9 l
  26. #define RECEIVE_DATA          ((uint16_t)0xEEEE)     /* Page is marked to receive data */
    ! n8 _' ~6 u* V7 Z) u$ [- w6 I; Q
  27. #define VALID_PAGE            ((uint16_t)0x0000)     /* Page containing valid data */
复制代码
     看代码第6行,这里设定的地址是: EEPROM_START_ADDRESS  ((uint32_t)0x08002000)。
) U! T$ N3 S) \% K
. X6 s5 V7 |0 t: j* f5 [7 I$ |. f而STM32F0xx_EEPROM_Emulation演示代码中eeprom.c中关于读的函数:- p+ P+ F7 D( o, P

7 n* _! v2 q+ h" t0 f5 U& w
  1. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)* c1 _! b, l) N9 [! K% u  t- [
  2. {
    , K2 q" ^" L% K5 J% o8 U, U- q
  3.   uint16_t ValidPage = PAGE0;
    , B! B6 J+ l7 r
  4.   uint16_t AddressValue = 0x7777, ReadStatus = 1;/ }8 Q$ i$ m* A5 ?
  5.   uint32_t Address = 0x08001000, PageStartAddress = 0x08001000;
    ' v' A" O+ P" _$ a* N
  6. .
    + M% ^0 F' v6 A% _9 d
  7. .) N7 _& \; P. K$ X" n4 X7 S& `# y' k" k
  8. }
复制代码
' [9 e; I! O. [) Y
      这里的地址是:Address = 0x08001000。PageStartAddress = 0x08001000;
3 q% d. }, o4 N7 Y      问题应该就出在这里。这个eeprom仿真代码是从STM32F1xx移植过来的。
% a0 Q5 a: ~  r4 C! V- j0 a
  K! x4 O. k+ g$ X! {+ F在STM32F1xx的eeprom.h中地址是这样的:$ ^2 i( }1 _4 k. o4 ~1 Q5 Z
  1. /* EEPROM start address in Flash */# y' R% j$ j2 Q
  2. #define EEPROM_START_ADDRESS    ((uint32_t)0x08010000) /* EEPROM emulation start address:
    ( t( i4 W6 ]" W% Q2 K6 @: p& c
  3.                                                   after 64KByte of used Flash memory */
复制代码
2 t# R# r& k4 a6 H
在STM32F10xx的eeprom.c中读函数是这样的:8 E1 S  B. P* B$ X5 c6 c& h
  1. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)1 R) b  L3 m1 `/ m% K
  2. {  k9 F4 d4 `2 |8 a
  3.   uint16_t ValidPage = PAGE0;
    9 s+ K  q+ R: t; u0 y( f2 E/ X; Y: S) x
  4.   uint16_t AddressValue = 0x5555, ReadStatus = 1;: ?, {$ y' w% H* B; Q
  5.   uint32_t Address =0x08010000, PageStartAddress =0x08010000;
    8 H# Z% P% g& `! X" L4 k$ I7 L
  6. .
    . j% Q. I; K0 H  {5 C
  7. .
    ( o8 V5 _: M7 G" O' e9 c, j$ H3 L
  8. }
复制代码
       ST工程师在移植F1到F0时忘记将eeprom.c和eeprom.h的读写地址统一,在STM32F0xx_EEPROM_Emulation写入首址是0x08002000,读出首址是0x08001000:读非所写。
7 F9 R; @, D0 g0 A: p7 ?! d5 ?$ [8 V  x$ |5 Y4 k
       而执行帖子开头的演示代码为什么没有发现读出错呢?由于在演示代码中写完flash操作后并未清空数组变量,DEBUG进入跟踪可知:由于读地址错误,并未执行读操作而直接退出。所以执行
1 T6 c  c% D+ f, IEE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);, I) Z6 ]7 p1 v9 o
这句时,实际上根本就没有读扇区、没有更新数组变量内容,数组变量里保留的是上次写操作留下的残余,所以运行的结果看上去是正确的,实际上读出错了。$ o* R- N7 r* j, ^1 m6 p

6 u+ N$ s! A; x; g7 J* m5 y0 _) H+ a) ?8 ]' p6 T
      修改F0的eeprom.c函数中错误之处,3 Z4 q- y1 X! t( F+ X
  1. uint32_t Address = 0x08002000, PageStartAddress = 0x08002000;
复制代码
     问题解决。这个固件库是2012年的古董,6年了,看来我是社区第一个成功使用STM32F0xx_EEPROM_Emulation的了!" B8 ?! \4 B# Q2 Q" E3 r4 [
      希望本贴对使用STM32F0xx_EEPROM_Emulation失败的网友有帮助,希望ST官方能更正错误的源码。# t. j. y2 e* n
! _9 U" U) Q; B  v+ [

6 T* q' J1 q, A$ k* V9 f+ D/ J2 F: H+ O2 B4 J* k  \& k- C( Q/ S
% |: K8 ^& a- ?6 I# U5 H
5 W7 V+ B& e1 S/ Z6 d* r' w
0 p1 u; }& y4 X" I! v

( j) p' u# K6 p, I/ T. f% ~/ }, [2 A5 O$ |; A8 P. {

& p: k" i8 h! K3 a# X2 M/ L3 k4 _: l) d$ k

评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2 很给力!

查看全部评分

赞 收藏 1 评论4 发布时间:2018-10-27 19:18

举报

4个回答
STM1024 回答时间:2018-10-28 14:35:35
不错,分析的很仔细
wenyangzeng 回答时间:2018-10-28 19:23:25
stm1024 发表于 2018-10-28 14:35
& |3 `( b0 @) a不错,分析的很仔细

5 n3 }1 \- V. l+ n2 N4 b( D谢谢支持!
MrJiu 回答时间:2018-10-29 09:56:48
不错!!!
wenyangzeng 回答时间:2018-10-29 10:18:42
MrJiu 发表于 2018-10-29 09:56
8 {+ y. W: y1 K3 t. S$ c9 F, m不错!!!

+ m& O4 C! Y/ I, @3 R( s: ~, Z谢谢版主!

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版