open/close一个文本文件每0.01秒写入一个文本文件是否正确?

Is it the right choice to open/close a text file for writing each 0.01 sec?

我必须通过加速度计收集数据,执行一些计算并将结果附加到文本文件中(在通过 SPI 连接的 MicroSD 卡中)。代码正在运行,但我应该每 0.01 秒将速度提高到一个日志。 MicroSD 以这种速度 open/close 是否正常?

#include "mbed.h"
#include "SDFileSystem.h"

SDFileSystem sd (SPI_MOSI_SD, SPI_MISO_SD, SPI_SCK_SD, SPI_SS_SD, "sd");

int main (void)
{
  mkdir("/sd/data", 0777);
  while (1)
  {
    // record from accelerometer and perform calculations
    FILE *fp = fopen("/sd/data/parameters.txt", "a");
    if(fp == NULL)
    {
      error("Could not open file for write.\n");
    }
    fprintf(fp, "%.4f\n", parameter);
    fclose(fp);
    wait_ms(100);
  }
}

我的问题是 while 循环永远不会结束:我必须连续写入数据并决定仅通过关闭设备来中断。这样 fclose(fp) 永远不会发生。

Is it healthy for the MicroSD to open/close at this speed?

穿的是写作。我不明白为什么打开和关闭应该很重要。但完全没有必要像你那样做。改为这样做:

FILE *fp = fopen("/sd/data/parameters.txt", "a");

if(fp == NULL) {
    error("Could not open file for write.\n");
}

while (1) {
    fprintf(fp, "%.4f\n", parameter);
    // If your worry is that the file buffer won't be written to disk
    // in case of a power off, just flush the stream.
    fflush(fp);
    wait_ms(100);
}

fclose(fp);

当然,检查 fprintffflush 的 return 值以检测错误是一个很好的做法。

My problem is that the while loop never ends: I have to write data continuously and decide to interrupt only by switching off the device. In this way fclose(fp) never happens.

听起来你需要的是 Journaling file system

当您认为 open/close 不够快时,您可以缓冲数据。 例如,只需从您的 acc 收集 100 个或更多数据点,然后每秒一次将它们写回。

在我的时代,SD 卡通常将其数据写入完整扇区,即使您只写入一个字节。我假设情况仍然如此,所以按照您的方式进行操作会多次磨损一个扇区而无需这样做。这就是缓冲很重要的原因。数据应以大约 512 字节(典型扇区大小)进行缓冲。建立缓冲区直到达到 512 字节,然后通过写入 SD 卡进行刷新。

char sd_buffer[512];
unsigned short buffer_idx = 0;
:
void append_buffer ( char *str )
{
   while ( *str )
   {
       sd_buffer[buffer_idx++] = *str++;

       if ( buffer_idx >= 512 )
       {
            FILE *fp = fopen("/sd/data/parameters.txt", "a");
            if ( fp == NULL )
                  return; // error
            // flush buffer
            fwrite(sd_buffer,1,512,fp);
            fclose(fp);
            buffer_idx = 0;
       }
   }
}
:
while (1) 
{
    char buf[32];
    sprintf(buf,"%.4f\n", parameter);
    append_buffer(sd_buffer,buf);
    wait_ms(100);
}

这只是意味着它将减少写入 SD 卡(在每个 512 字节间隔)

免责声明:未经测试

Ps。 open/close 文件现在位于 append_buffer 中,因此任何文件系统缓冲区也将被刷新。

如果您遇到循环问题。使用 state machine

My problem is that the while loop never ends: I have to write data continuously and decide to interrupt only by switching off the device. In this way fclose(fp) never happens.

在上述情况下,每 100 毫秒添加一个 fclose 仍然无济于事。如果在写入过程中发生关机,您可能会丢失最后写入的数据。

  1. 如果你没问题,可能会丢失最后一次写入,那么

    • 缓冲写入无论如何都会发生在行尾字符 \n
    • 所以你可以在 main 结束时关闭文件,(或者根本不关闭)
  2. 如果想关机也一直写入SD卡,设计就比较复杂了。您将需要 -

    • 检测断电。您可以使用 ADC 通道。
    • 电源上的一个电容器,它将为控制器供电一段时间(可能是 50 毫秒)
    • 关闭例程将 运行 关闭电源,确保缓冲写入完成并关闭文件。