STM32
直播中

贾桂林

8年用户 1607经验值
私信 关注
[问答]

STM32F407在const绝对定位数组后,复位后运行不正常是怎么回事?

最近我在写一款程序,在初始化定义如下代码:
     const u8  a[2] _attribute_((at(0x08020000))),也就是把数组的地址定义在flash空间的0x08020000这个位置。
   然后在串口中断中对这个地址所在的扇区进行擦除,代码如下:
  __disable_irq();
    FLASH_Unlock();
   FLASH_EraseSector(FLASH_Sector_5,VoltageRange_3);
   FLASH_Lock();
__enable_irq();
这个时候,只要程序不复位,串口收发都可以,程序运行正常,但是只要程序一复位,就会运行异常,我们通过检查,发现是初始化的数据改变了,比如我们在初始化定义了u8  a=123,那么在复位后,a=0xff。
出现这个问题的原因是KEIL5的编译器把a=123,中断常数123放进了FLASH当中,而且是放在最后使用的一个FLASH地址中,也就是放在0x08020000这个扇区当中,这样,擦除以后,只要复位后上电,那么读出来的数据就是FF,所以很多定义的初始化变量全部变成了FF,解决问题的办法是在0x08020000这个扇区后面再定义一个扇区,也就是再加一句const u8  a[2] _attribute_((at(0x08040000))),这样,初始化的常量就会放在0x08040000这个扇区,那么再对0x08020000这个扇区进行擦除和写操作就没有影响了!

回帖(1)

刘玉兰

2024-3-25 17:51:28
根据您提供的信息,问题可能出现在复位之后没有正确初始化数组的位置。

在STM32F407中,const修饰的数组默认存储在Flash存储器中。而在您的代码中,您使用了`__attribute__((at(0x08020000)))`将数组的地址定义在Flash空间的0x08020000位置。这是合法的,但需要确保该地址是有效的Flash地址。

在复位后,芯片会重新初始化,可能会导致程序无法正确访问该地址,从而导致程序运行异常。为了解决这个问题,您可以在复位后重新初始化这个数组的位置。

您可以在复位之后,通过检查Flash是否被正确擦除,确定是否执行了擦除操作。您可以使用以下代码检查Flash的擦除状态:

```
void checkFlashEraseStatus() {
    FLASH_Status eraseStatus;
    eraseStatus = FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);

    if (eraseStatus != FLASH_COMPLETE) {
        // 擦除失败,执行相应操作
    }
}
```

另外,尽量避免在中断中执行耗时较长的操作,以免影响程序的正常运行。您可以将擦除Flash的操作放在其他地方执行,比如在主循环中定期检查是否需要擦除Flash。

希望以上信息能解决您的问题。如果您还有其他疑问,请随时追问。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分