c - STM32L151片上EEPROM写入时间

标签 c embedded stm32 microcontroller eeprom

当我在代码中应用这些函数时,我可以在 STM32 片上 EEPROM 上写入和读取数据。

#define EEPROM_BASE_ADDR    0x08080000
#define EEPROM_BYTE_SIZE    0x03FF

.

//Byte write
void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
{
   uint16_t i;
   HAL_StatusTypeDef status = HAL_OK;

   HAL_FLASHEx_DATAEEPROM_Unlock();
   for(i=0;i<len;i++)
   {
       status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);
       Data++;
   }
   HAL_FLASHEx_DATAEEPROM_Lock();
 }

.

//Byte read
void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len)
{
   uint8_t *wAddr;
   wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);
   while(Len--)
   {
       *Buffer++=*wAddr++;
   }
}

我的问题是仅一个字节的 EEPROM 写入过程花费了太多时间(6.57ms)。我怎样才能减少这个?

最佳答案

数据手册指出删除时间通常为 3.28 毫秒,写入时间也相同。 2 x 3.28 = 6.56ms 与您的观察结果相符。

您可以通过不重写而简单地按顺序写入连续值,使用最后写入的值作为当前读取的值,将有效时间减半。您必须在启动时进行扫描,以找到最后写入的有效值,最终您将不得不删除更大的 block 。

当您写入 EEPROM 时,如果应用程序的实时性能和精度至关重要,请务必仅使用双字写入/删除操作以避免总线停顿:

从 RM0038 起:

During a write/erase operation to the NVM (except Half Page programming or Double-word erase/write), any attempt to read the same bank of NVM stalls the bus. The read operation is executed correctly once the programming operation is completed. This means that code or data fetches cannot be performed while a write/erase operation is ongoing in the same bank.

此问题的解决方案是使用 RTOS 内核并有一个专门用于写入 EEPROM 的后台服务线程,以便其他更高优先级的线程可以继续同时执行有用的工作。您可以简单地将写指令(地址+长度+数据)消息传递到队列上以在后台进行服务。问题是,如果您尝试在写入操作正在进行时同时读取 EEPROM,则可能会遇到上述总线停顿问题以及数据一致性问题。

同时解决性能问题的更安全解决方案是让 EEPROM 服务维护 EEPROM(或其一部分)的 RAM“缓存”副本,以便写入指令修改 RAM(在调用线程上下文中)将写请求传递给后台 EEPROM 写入线程。然后应用程序从 RAM 副本而不是从 EEPROM 读取(通过访问器函数 - 不是直接)。您需要一个互斥体来确保数据一致性,但效果是将 EEPROM 读/写性能与应用程序性能和应用程序线程解耦,EEPROM 操作看起来与 RAM 操作一样快(更少的 API 调用和互斥体开销)

如果您无法保证 EEPROM 更新期间的电源安全,您在任何情况下都可能还需要某种数据完整性检查机制。维护数据的两个 EEPROM 副本以及最后写入的序列号是实现电源故障一致性的简单方法。在这种情况下,EEPROM 线程会将整个 RAM 缓存(具有可重新启动的回写延迟)一次性写入交替的双冗余 block 。启动时,“事件” block 是具有最高有效序列号的 block ,并被复制到 RAM 缓存。

如果您的系统可以保留电源(例如电池备份),您将从 32 x 32 位(128 字节)备份寄存器 block 获得更好的非 volatile 存储性能 - 如果这对于您的应用程序来说足够了。

外部串行(SPI 或 I2C)EEPROM 具有类似的写入/删除延迟,但没有总线停顿问题,并且可能具有更高的耐用性。此外,您通常可以传递 64 字节“页面”并进行编程,一次操作的时间不超过一个字节。此外,上述 RTOS 服务线程解决方案也可用于外部 EEPROM,并且您可以使用 DMA 或中断驱动通信来实现并发。

FRAM(铁电 RAM)等替代非 volatile 存储器技术速度更快。

关于c - STM32L151片上EEPROM写入时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71739466/

相关文章:

MS-DOS 的 C 编译器

MontaVista Linux 的 Java

microcontroller - 如何在Cortex-M7(STM32F746)上使用不同的DMA channel 使用相同的DMA流?

arm - 在 Master (SPI) 中设置 nss_soft

c - 嵌入式 C 语言中的 "Super Loop"是什么?

C 预处理器 - 无需多重解析即可连接字符串

c - 网络字节序遍历结构体(Big Endian) --- C语言

c - C中的递归函数返回值而不返回

c - 为什么我做的计算器不能用?

Linux block 设备模拟 & Fuse