fukasawa
2019年10月10日 18時35分
いつもお世話になっております。
Armadillo-440を使用中にSDカードがRead-Onlyになってしまうことがあります。
これを防ぐ方法がありましたら教えて下さい。
# 発生条件
Read-Onlyになる条件ですが、
コマンドを直接入力するような方法では発生せず、プログラムからファイル書き込みした場合に発生します。
ただ、ファイルパスも書き込み内容が同じであっても常に発生するわけではないようです。
正常→Read-Only発生時のメッセージが以下です。
FAT-fs (mmcblk0p1): error, fat_free_clusters: deleting FAT entry beyond EOF FAT-fs (mmcblk0p1): Filesystem has been set read-only
# とりあえずの解決方法
また一度Read-OnlyになってしまったSDカードは再起動してもそのままなので、
起動時に常にfsck.vfatを呼ぶようにしました。
/etc/init.d/misc
#!/bin/sh . /etc/init.d/functions PATH=/bin:/sbin:/usr/bin:/usr/sbin echo -n "Mounting ramfs /home/ftp/pub: " mount -t ramfs ramfs /home/ftp/pub chmod 0777 /home/ftp/pub check_status fsck.vfat -a /dev/mmcblk0p1 mount -a
すると、起動時に以下のようなメッセージが出るようになりました。
~~ Mounting ramfs /home/ftp/pub: done dosfsck 2.11, 12 Mar 2005, FAT32, LFN Warning: FAT32 root dir is in a cluster chain, but a separate root dir area is defined. Cannot fix this easily. There are differences between boot sector and its backup. Differences: (offset:original/backup) 0:eb/00, 2:90/00, 3:20/00, 4:20/00, 5:20/00, 6:20/00, 7:20/00, 8:20/00 , 9:20/00, 10:20/00, 12:02/00, 13:40/00, 14:84/00, 15:18/00, 16:02/00 , 21:f8/00, 24:3f/00, 26:80/00, 29:20/00, 33:d8/00, 34:77/00, 36:be/00 , 37:03/00, 44:02/00, 48:01/00, 50:06/00, 64:80/00, 65:01/00, 66:29/00 , 67:f8/00, 68:4e/00, 69:16/00, 70:90/00, 71:4e/00, 72:4f/00, 73:20/00 , 74:4e/00, 75:41/00, 76:4d/00, 77:45/00, 78:20/00, 79:20/00, 80:20/00 , 81:20/00, 82:46/00, 83:41/00, 84:54/00, 85:33/00, 86:32/00, 87:20/00 , 88:20/00, 89:20/00, 318:00/55, 319:00/aa, 320:00/52, 321:00/52, 322:00/61 , 323:00/41, 510:55/00, 511:aa/00 Not automatically fixing this. FSINFO sector has bad magic number(s): Offset 0: 0x0077d800 != expected 0x41615252 Offset 484: 0x00000000 != expected 0x61417272 Offset 510: 0x0000 != expected 0xaa55 Auto-correcting it. File syFAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck. stem has 122591 clusters but only space for 7662 FAT entries. Running local start script (/etc/config/rc.local). ~~
結果として、再起動後は書き込み可能になるのですが、「Cannot fix this easily.」といった内容が含まれているのが気になります。
# SDカード製品
SDカードはAF4GUD3A-OEM (4GB) を使用しています。
https://www.digikey.jp/product-detail/ja/atp-electronics-inc/AF4GUD3A-O…
動作保証のある以下の製品 AF4GUDI とはわずかに型番が異なるのですが、同じ製品と考えてよいのでしょうか。
https://armadillo.atmark-techno.com/node/2035
コメント
fukasawa
回答ありがとうございます。
> SD使用時の書き換え頻度はどれくらいでしょうか。
起動してから数十秒後に1回まとめて書き込きます。
以降は操作頻度によりますが、最大で2分に1回ほどです。
1回の書き込みで6ファイルほどを連続で書き込みます。
ファイル書き込み部分のコードは以下です。
int write_text_to_file(const char *filepath, const char *str, bool isAdd) { //書き込み先のディレクトリがなければ作る make_directories(filepath); //指定したファイルをオープン、書き込み、クローズする FILE *pfile = fopen(filepath, isAdd ? "a" : "w"); if (!pfile) exitfail_errno(nameof(fopen)); int len = fprintf(pfile, str); if (len < 0) exitfail_errno(nameof(fprintf)); fclose(pfile); return len; }
at_makoto.sato
佐藤です。
お使いの SDカードの書き換え回数の上限を仮に4万回とすると、理想的な環境下でも 4GB * 40000 = 160TB で寿命になるかと思います。
このようになっているようであれば、SDカード自体を交換したほうが良いかもしれません。
SDカードの選定ポイントについては以下が参考になるかと思います。
https://users.atmark-techno.com/comment/reply/4154/7613
fukasawa
at_makoto.sato
fukasawa
at_makoto.sato
fukasawa
fukasawa
解決しました!
> fclose() の前に fflush() と fsync() をすると改善されないでしょうか。
やってみましたが、これだけでは変わりませんでした。
デバッグ出力などを追加してみたところ、複数ファイルの連続書き込み時の3~4個目ぐらいでエラーしていました。
そこでfclose()の直後に1msecほど待機させるようにすると、エラーが発生しなくなりました。
~~ fflush(pfile); fsync(fileno(pfile)); fclose(pfile); //連続して書き込む場合にエラーするのを防ぐために、少し待つ int sleepTime_msec = 1; usleep(sleepTime_msec * 1000); return len;
fflush()とfsync()なしでもエラーは発生しませんが、あった方が良さそうなので、入れるようにいたします。
ありがとうございました。
at_makoto.sato
2019年10月11日 9時46分
佐藤です。
下記の投稿でもありますが、SDカード自体の寿命の可能性があります。
https://users.atmark-techno.com/comment/1944#comment-1944
SD使用時の書き換え頻度はどれくらいでしょうか。