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

【实战经验】STM32 擦除内部 FLASH 时间过长导致 IWDG 复位

[复制链接]
STMCU-管管 发布时间:2019-3-19 09:33
STM32 擦除内部 FLASH 时间过长导致IWDG 复位6 }' @  q$ i1 ^- A2 P
- a. l' _8 e1 O
1 前言
- }+ K5 z8 H4 ^4 a" Q& r
, A% q: J5 r4 V+ ~1 O* h
客户反馈在使用 STM32F412 的时候,擦除 sector 8~11 发现时间过长,从而导致意外触发IWDG 复位。
" a" n) s$ O: F: q& C0 H$ |4 L
" I& ~  t) @) W) N3 ^$ x2 问题分析 9 |8 t" _+ ]2 m/ b; p6 q5 y
) ~8 Z' j0 L0 {: O+ g$ g0 h# o) W+ O" \
2.1 问题详情
7 V$ T* C, ^) a# a( n0 D' P3 X! }. ?" ?' C, g: v+ Z" c( H% Z
通过与客户邮件和电话沟通,了解到客户主要是想使用内部 FLASH 暂时保存 IAP 升级时的程序数据,在 IAP 升级的过程中,需要首先擦除内部 FLASH 中一块足够大的空间,然后再写入升级数据。客户的工程中有使用到 IWDG,喂狗间隔大约 1.5S,客户的通过 SysTick 的方式计算出擦除 Sector8大约需要 2ms,因此认为若一次擦除 sector8~11 大约需要 8ms,于是在代码中一次性擦除 sector8~11后最后再来喂狗,但是,这样会触发 IWDG 复位,这个与预期不一致,固此产生疑问。' d1 M0 G4 c) L) X1 p
( \, V5 S. S2 j4 y2 a
2.2 问题重现 6 @9 A. y2 h( B4 t

, l6 n/ A5 F/ c9 U8 v使用 NUCLEO-F412ZG 板尝试重现客户问题,主要代码如下:0 A5 n. x% Y, ~8 s5 o& z8 z
0 L# [. G! M' c+ z. y
int main(void)9 i4 i8 {* }9 l+ Q' ^/ P: d- q
{
0 Y5 `* k- F: l: ]" g2 @) I /* USER CODE BEGIN 1 */
5 }+ M8 e$ e6 j  @uint32_t beginTick =0,endTick =0;
+ k0 y' b7 R9 f. _uint32_t curSysTick=0,endSysTick =0;7 ?0 D  T% h' d6 f3 w0 z7 p
/* USER CODE END 1 */
  Y6 q7 I5 Y1 |# |, N /* MCU Configuration----------------------------------------------------------*/
* ^. _' l4 N) b$ L  A /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
5 c& y- O1 z; h) Q( {+ c HAL_Init();
$ l' w. @' f. u+ R7 W /* Configure the system clock */, n% q" A- f/ O2 C' a$ u1 d
SystemClock_Config();
+ n3 p" x3 \2 b( Q8 _0 f /* Initialize all configured peripherals */+ k2 R  k$ w* ]. m
MX_GPIO_Init();
" ]' Q) A3 c" F$ \* }" S MX_IWDG_Init();
; ~  `  s7 E& L- O' C3 v2 g( y /* USER CODE BEGIN 2 */1 ?- t# m5 l7 J; V0 k3 Y
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) //如果是看门狗复位) h! M" f' P) `" a8 x3 Q( f2 n" {( j; ?
{% I# U6 u# g! b) M2 L
/* Clear reset flags */
' ^( @4 z( D' aHAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
8 v' v: i( L- N2 ]4 o* ^" K __HAL_RCC_CLEAR_RESET_FLAGS();
9 f; r+ q1 |+ [! y7 pError_Handler();
: D' A9 A$ \; o' w' U# v }9 m$ _; a3 u& s, Q  C  _
HAL_FLASH_Unlock();
5 p( I9 o( @/ j7 ^8 ~# f /* Fill EraseInit structure*/" Q0 }( k" J4 a& o' M
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
. ^3 o0 x9 Z1 E# B2 x1 s EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
. K/ W+ d" `, }% v EraseInitStruct.Sector = FLASH_SECTOR_8;
9 n0 H# r3 n  i' } EraseInitStruct.NbSectors = 1;
. N% R# R' |- w  g0 ~4 O// if(HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
3 a" X# [  S. Y// {
4 J5 R, g2 _) I' Z- z! E: j. [+ m// Error_Handler();0 V/ M8 u( A! J1 k$ r" A
// }: x2 ~0 ~; M1 @
beginTick =HAL_GetTick();
5 }# o" E8 O; U8 f7 E* x% I- kHAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
' F6 A! e* C) N# t& E9 F$ p9 C5 YcurSysTick =SysTick->VAL;5 V. W! S6 W0 I& D1 X- K6 C$ p
if(HAL_FLASHEx_Erase_IT(&EraseInitStruct)!= HAL_OK) //擦除 sector8  y+ o  G1 d- R' `7 I$ H5 X5 O
{
1 z. _# Q" |: V, d& B3 P+ h" k* KError_Handler();& A" D% H4 S8 o" _/ Q6 U& }
}% ?9 T& H+ v2 \) f% u0 i
endSysTick =SysTick->VAL; // curSysTick, endSysTick 保存着 SysTick 寄存器的值; t; |4 y1 _" L# C6 A; e
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET); //PC8 波形表示擦除 FLASH 的时间间隔4 B8 n/ e- B1 m- o+ L  Z
endTick =HAL_GetTick(); // beginTick, endTick 保存着全局变量 Tick 的值
0 G9 `& m' ~! {* {8 [6 D6 A. Dg_TickCount =endTick -beginTick; //变量 Tick 的时间差
) V" [) g5 H- c1 i" o- AHAL_IWDG_Refresh(&hiwdg);' H4 }0 b, P8 @/ z9 A+ \
/* USER CODE END 2 */
) K( Y! I1 W0 A- \, j$ m /* Infinite loop */. p( S8 a, P: o* L
/* USER CODE BEGIN WHILE */
, i: k( O1 W: v- @- O while (1)* K* G: }/ Z# O3 `* K
{  T% D; U, }- Z7 B( E  {
/* USER CODE END WHILE */) g5 l6 i+ e) B" }
/* USER CODE BEGIN 3 */8 Q& ^' r3 @1 j5 Z
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK), n3 a. m' j0 \- p( t8 h7 X5 |& {2 m
{1 I4 F# _% c4 L$ _* H7 c
/* Refresh Error */2 A8 t2 @$ Y8 z4 M# J7 ]
Error_Handler();9 x* Y3 q" d* ~5 Z, B; G5 ?8 h% l
}4 \4 }3 a/ k  ~
HAL_Delay(10);
6 m+ V8 R$ l0 q2 h/ r0 p# Y$ ^; g }
8 G( f+ B0 Q6 k, @ /* USER CODE END 3 */

7 c; |: l; T6 N; z% z6 m2 [# j) h此外,同时在每个 SysTick 中断输出一个波形,用来检测 SysTick 是否正常# d$ [0 K# H$ ?( L' i

& p5 U) N) ~9 y2 j
void HAL_SYSTICK_Callback(void)
) e8 d4 ^" }9 ?0 V{+ d9 ^  P7 N; [
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_11);//用 PA11 来检测 SysTick 波形- P( K' S' w% ^/ L6 F
}

5 L1 h' {0 c' W' X8 [最终得出的波形如下:( m9 }0 s! m) K4 @; L2 ^

& B2 |. c6 `  c. c( ^" Y
1.png
............
' X4 S$ T6 c4 I$ s! @0 Y; D
想了解更多,请下载原文阅读

: v* }" z* i; e* i9 Q/ |/ F) f
8 G% c+ J" f; @; ?& K2 t' r2 X  h
赞 收藏 评论2 发布时间:2019-3-19 09:33

举报

2个回答
七哥 回答时间:2019-3-19 10:20:07
测试程序分析,步骤清晰。但是不明白,擦除时间怎么那么长。
Kevin_G 回答时间:2019-3-19 12:56:46
Flash的擦除时间是固定的么?查找哪个资料呢?
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版