4

わかりました、最初に私の質問を明確にするのに役立つ少しの背景:

センサーから特定のデータを収集し、GSM モデムを使用してサーバーに送信するデバイスに取り組んでいます。GSM 接続は 100% 信頼できるわけではないため、未送信データを SD カードに書き込むロギング メカニズムが含まれます。

PC でログを読み取れるようにするため、ファイル システムを提供するためにChan の FatFsモジュールを使用しています。

今、私は FAT システムの境界条件をテストしています。つまり、カードを完全にいっぱいにしようとしています。

最初の実行では、ファイルを開き、ドライブがいっぱいになるまで文字列を書き続けるようにコードを設定しました。プログラムは書き込みのたびに同期します。

コードを一晩実行したままにしました。

翌日、SDカードを調べました。ファイルのサイズはわずか 150 MB であることがわかりました。約 120 万行が書き込まれました。カードから読み取ることはできますが、書き込みやフォーマットはできません。

次回も同様のテストをしてみましたが、今回はf_lseek()事前にファイルを1GBに割り当てる機能を使いました。次に、その制限に達するまでそのファイルに書き込みます。今回は、50 回の書き込み後にデータが同期されます。次に、そのファイルを閉じて、別のファイルを開いて同じことを行います。

ご想像のとおり、その日、別の勇敢な小さなカードが心を失いました。

だから、これらは私が助けて欲しいものです:

  1. 大量のデータを書き込む際にカードの損傷を防ぐ方法は?
  2. ファイルを長時間開いたままにしておくと、悪影響はありますか?

完全なコードは長すぎる可能性があるため、書き込みが行われる主要部分を次に示します。

for(file_count=3;file_count>=0;--file_count){

    ax_log_msg(E_LOG_INFO,"===================================");

    ax_log_msg(E_LOG_INFO,file_names[file_count]);


    f_open(&file_ptr,file_names[file_count],FA_WRITE|FA_OPEN_ALWAYS);

    if(result!=FR_OK){

        ax_log_msg(E_LOG_INFO,"\n\rf_open Failed\n\rResult code");
        ax_log_msg(E_LOG_INFO,FRESULT_S[result]);

        continue;

    }

    ax_log_msg(E_LOG_INFO,"\n\rf_open Sucessfull");

    result=f_lseek(&file_ptr,FILE_SIZE_LIMIT_1GB);

    if(result!=FR_OK){

        ax_log_msg(E_LOG_INFO,"\n\rf_lseek Failed for preallocation\n\rResult code");
        ax_log_msg(E_LOG_INFO,FRESULT_S[result]);

        f_close(&file_ptr);

        continue;

    }

    ax_log_msg(E_LOG_INFO,"\n\rf_lseek Sucessfull for preallocation");

    f_lseek(&file_ptr,0);

    bytes_to_write=sizeof(messages[file_count]);

    write_count=0;

    while( (f_tell(&file_ptr) < FILE_SIZE_LIMIT_1GB )){

        result=f_write(&file_ptr,messages[file_count],bytes_to_write,&bytes_written);

        if(result==FR_OK){
            ++write_count;

            if(write_count%50==0){

                f_sync(&file_ptr);
            }

        }else{

            ax_log_msg(E_LOG_INFO,"\n\rWrite failed\n\rFRESULT=");
            ax_log_msg(E_LOG_INFO,FRESULT_S[result]);

            break;

        }

    }

    f_close(&file_ptr);


}

ノート :

  1. ax_log_msg() は、コンソールに出力するデバイス ファームウェアの一部です。
  2. FRESULT_S[result] は、列挙結果コードを文字列に変換するために使用されます。

不足しているデータがある場合は、それを記載してください。

ありがとうございました

4

2 に答える 2

3

フラッシュのたびにブロック全体がフラッシュされるのを避けるために、データのブロック全体 (おそらく 4 KB) をバッファリングする必要があるでしょう。ただし、明示的に呼び出さない限り、ファイルシステムまたはドライバーがこれを行う必要がありますfflush。これが本当の教訓です。

なぜそんなに頻繁に同期する必要があるのですか? おそらくタイマーは、レコード数ごとの間隔よりもうまく機能するでしょうか?

于 2014-07-24T10:49:22.720 に答える