打开/关闭文本文件以每0.01秒写入一次是正确的选择吗?

时间:2019-05-21 07:43:32

标签: c loops fopen fclose

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

#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)永远不会发生。

4 个答案:

答案 0 :(得分:3)

  

以这种速度打开/关闭MicroSD是否健康?

戴着它的是文字。我不明白为什么打开和关闭很重要。但是完全没有必要像你一样做。改为这样:

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的返回值以检测错误。

  

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

听起来您需要的是Journaling file system

答案 1 :(得分:3)

在我这一天,即使您正在写一个字节,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。现在,打开/关闭文件位于append_buffer中,以便也刷新所有文件系统缓冲区。

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

答案 2 :(得分:2)

当您认为打开/关闭不够快时,可以缓冲数据。 只需从您的帐户收集100个或更多数据点,然后每秒写一次即可。

答案 3 :(得分:1)

  

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

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

  1. 如果还好,可能丢失了最后一次写入,则

    • 缓冲写入将始终在行字符\n的末尾发生
    • 因此您可以在main的末尾(或根本不关闭)
  2. 如果即使在关机时也希望始终在SD卡中写入数据,则设计会更加复杂。您将需要-

    • 检测电源关闭。您可以使用ADC通道。
    • 电源上的电容器将保持控制器通电一段时间(也许50ms)
    • 关闭例程,该例程将在断电时运行,以确保缓冲写入操作完成并关闭文件。