请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
STMCU-管管 发布时间:2019-3-19 09:33
STM32 擦除内部 FLASH 时间过长导致IWDG 复位
# }; v. w$ a  x) w& p

: p) l1 s- V& L7 q1 前言
& r% X: O. }# t) X0 O2 a$ m/ _
: Y2 u* f; U/ Q8 `) }1 p
客户反馈在使用 STM32F412 的时候,擦除 sector 8~11 发现时间过长,从而导致意外触发IWDG 复位。
" E# {% n# e) \8 n! h5 v8 X" {4 D( Q( j+ h
2 问题分析 * I2 _/ l* f4 f' v$ v4 o
+ N) x6 d. h6 \( J0 i) w
2.1 问题详情 6 _( S' e( |4 J: d2 \0 {
* {7 r0 K3 }! }2 I2 E3 }5 ~: J% X
通过与客户邮件和电话沟通,了解到客户主要是想使用内部 FLASH 暂时保存 IAP 升级时的程序数据,在 IAP 升级的过程中,需要首先擦除内部 FLASH 中一块足够大的空间,然后再写入升级数据。客户的工程中有使用到 IWDG,喂狗间隔大约 1.5S,客户的通过 SysTick 的方式计算出擦除 Sector8大约需要 2ms,因此认为若一次擦除 sector8~11 大约需要 8ms,于是在代码中一次性擦除 sector8~11后最后再来喂狗,但是,这样会触发 IWDG 复位,这个与预期不一致,固此产生疑问。( V$ `3 i& t4 Y* M
9 y: L  }/ ^3 f. I6 T5 k7 \6 n- v
2.2 问题重现 2 g8 z% f8 H* `$ ?1 i3 C6 K

$ e/ g# D+ o% V使用 NUCLEO-F412ZG 板尝试重现客户问题,主要代码如下:
. G* y" b' [4 T3 I
: \9 h( W) D7 }6 F7 m3 b5 _
int main(void)
& r; i( b1 {7 V# ^/ A8 N  C1 L{" n, v$ u% R; n% q4 G; ?: m
/* USER CODE BEGIN 1 */
+ V. D8 r$ J$ duint32_t beginTick =0,endTick =0;
. p' U; }0 q* z& C& D* o0 Euint32_t curSysTick=0,endSysTick =0;5 A* X: r2 ?# k9 z. d" I
/* USER CODE END 1 */
) m0 t' h. o8 n /* MCU Configuration----------------------------------------------------------*/
/ c3 R. q; r) E( M* C! w( F$ G /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
, z$ Q' n: ]7 L% b* G/ V HAL_Init();
, u9 e  [& q# s3 o- J5 I! ^ /* Configure the system clock */
7 m4 p5 e0 a1 j% B& c SystemClock_Config();
  Z: U* [+ V7 K0 u. g, N" W8 r/ N0 \ /* Initialize all configured peripherals */+ `' _9 p6 M& }+ Y; o
MX_GPIO_Init();
/ \0 M: i: m: z: V. K# | MX_IWDG_Init();: v/ p; u+ i: |6 }
/* USER CODE BEGIN 2 *// J* t$ d: b/ Q- H
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) //如果是看门狗复位
) a. [/ p/ ]2 R" {) v {8 g1 B# b" Q. J2 h2 v' \
/* Clear reset flags */& w! [- _7 U; D7 m. h
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);6 J/ P8 b; c. P5 M$ W. P
__HAL_RCC_CLEAR_RESET_FLAGS();
+ b( r* y3 b+ yError_Handler();
8 Q! k7 m! {$ m1 h% A6 V  O }8 u& h; [; G6 C1 q+ F" |( l
HAL_FLASH_Unlock();& U3 ^: K9 O" l6 S3 C# Z# G
/* Fill EraseInit structure*/
1 s6 f7 o2 K2 a# }. z EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
" z$ E$ W/ p5 Y& n" I EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;5 V+ v8 k* F# z/ c1 ]; ]4 R4 c
EraseInitStruct.Sector = FLASH_SECTOR_8;4 R1 S$ C5 y  O+ t6 w1 l: x
EraseInitStruct.NbSectors = 1;' ]4 [: R$ s. G6 D( x, T5 m+ x
// if(HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
- z! V; u, L( T7 ]/ G$ S! k// {! E  Q9 }* z+ K5 T. R
// Error_Handler();
6 R& [7 G. v6 F4 I// }
7 ]: U+ Q7 H8 i& P) [2 obeginTick =HAL_GetTick();2 u. e! Q  e1 P* Q; T
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
4 @' c, Q" m) x5 b, YcurSysTick =SysTick->VAL;
! @" ~% l& A! ]+ h5 e4 Rif(HAL_FLASHEx_Erase_IT(&EraseInitStruct)!= HAL_OK) //擦除 sector8& X7 p, P2 [* F9 w3 E
{0 r4 R6 y6 P3 A% \9 }2 f* x( ~
Error_Handler();# ?2 r; i( v( m$ M
}
/ k' H* D4 i7 o( x, Y2 `  O9 R8 NendSysTick =SysTick->VAL; // curSysTick, endSysTick 保存着 SysTick 寄存器的值7 ~" s- P% A0 s! g
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET); //PC8 波形表示擦除 FLASH 的时间间隔% _7 y. _1 ?; K* l- @" |9 D
endTick =HAL_GetTick(); // beginTick, endTick 保存着全局变量 Tick 的值
6 M. ?$ }' M5 x% z5 c* l! \  Jg_TickCount =endTick -beginTick; //变量 Tick 的时间差7 b" P$ U( V0 B
HAL_IWDG_Refresh(&hiwdg);
8 @& f2 \8 @" _8 ^ /* USER CODE END 2 */
+ ?' g! N* z; q  i" O% i: U. |/ q /* Infinite loop */4 ]8 G! C! [# k
/* USER CODE BEGIN WHILE */
# n4 T1 _0 T: L2 |! A while (1)8 C3 h$ W- W) a- x" G) Z
{
$ J0 W$ w* `5 r/ u$ _ /* USER CODE END WHILE */- P9 h2 ^+ T9 z# _8 Q
/* USER CODE BEGIN 3 */$ W6 k: Y8 A( |' w6 F7 R: d6 e
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK). T- ?! {" |  A# H2 j$ K
{
6 ^: I( {6 F  A  g$ I: p /* Refresh Error */5 [$ W6 I7 ]! [* g% q: k5 P
Error_Handler();6 _8 W5 C. Z2 h: n7 L" A
}6 u$ u) }8 I& J: u% V( l$ {5 B3 @' D
HAL_Delay(10);, P$ e$ g$ ~( r' Z$ @; ?
}0 a5 g# _( M1 u3 v9 y: R3 C) D
/* USER CODE END 3 */

+ ^7 d  b/ p/ h& B& R4 p此外,同时在每个 SysTick 中断输出一个波形,用来检测 SysTick 是否正常4 L9 |& r; i9 O6 t1 t" P' h: }, m. o

2 ^/ ~0 i* C; h4 T, v. U
void HAL_SYSTICK_Callback(void)
7 {/ t) V9 g* C# P( V0 r2 [{( @$ P+ o3 W( E# f0 L1 ~9 g
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_11);//用 PA11 来检测 SysTick 波形
: W$ v/ w6 H( Y9 W}
% C* a9 d/ v. B9 k# b! ^/ [5 o
最终得出的波形如下:
. E- ~& Z8 p1 g  H: w  w  F* c7 }" O
1.png
............

9 B# |. }, q3 K. X
想了解更多,请下载原文阅读

9 h* h' o/ d5 ]/ A5 v3 K
% N/ X, H  ~2 c+ f6 Q2 G3 Q
收藏 评论2 发布时间:2019-3-19 09:33

举报

2个回答
七哥 回答时间:2019-3-19 10:20:07
测试程序分析,步骤清晰。但是不明白,擦除时间怎么那么长。
Kevin_G 回答时间:2019-3-19 12:56:46
Flash的擦除时间是固定的么?查找哪个资料呢?

所属标签

相似分享

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