なんやこれ、よくわからん。。。
psoc6にfatfs入れて、f_utimeで軽くつまずいたのでまとめます。
f_utimeとは
f_utimeはファイルのタイムスタンプを設定する関数です。
chanさんのページはこちら
このサイトのコード例にあるように第1引数objにファイルパスを指定して、第2引数fno構造体に入っている日時情報に更新する、という動作です。
FRESULT set_timestamp (
char *obj, /* Pointer to the file name */
int year,
int month,
int mday,
int hour,
int min,
int sec
)
{
FILINFO fno;
fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
return f_utime(obj, &fno);
}
簡単そうですが、ファイルパスの指定方法や事前に変数設定が必要だったりして、初見だとちょっと苦労するんですよね。
なので、順に説明していきます。
ffconf.hの設定
まずやらないといけないのが、ffconf.hの設定です。
FF_FS_READONLYを0、FF_USE_CHMODを1にします。
chanさんのライブラリをそのまま持ってきた状態だと、たぶんFF_USE_CHMODが0になってます。
いずれも設定できたら、ffconf.hはOKなので次いきます。
ファイルパスの指定方法(第一引数)
まずはchanさんのこちらのページをご覧ください。
ffconf.hにあるFF_FS_RPATHの設定によって、相対パスか絶対パスか設定でき、初期設定はFF_FS_RPATH=0で、絶対パスです。
※たぶんRPATHはRelated Path(=相対パス)の略。
で、FatFSには論理ドライブの概念があって、標準だとドライブ0(ゼロ)が割り振られてるんですね。
(f_chdrive関数でドライブ番号は変更できますが、これはいったん置いときます)
ドライブ0にファイルが展開されていて、ドライブ0に今いる、ということは意識しておきましょう。
なので、例えば、1.txtというテキストファイルのタイムスタンプを設定したい場合、絶対パス指定されているなら、
f_utime("1.txt", &fno);
となります。
0:/1.txtとか、/1.txtとかしなくてよいです。単純にファイル名だけを与えます。
対象ファイルが開いているときはタイムスタンプ設定できない?
私のつまずいた点として、f_utime関数を使うタイミングがあります。
f_openでファイルを開いて、f_writeで書き込みをし、f_utimeでタイムスタンプ設定し、f_closeでファイルを閉じる
。。。
これはダメでした。f_closeしたあとにf_utime関数を呼ぶ必要があります。
ファイルを開いているときのf_utime関数の戻り値はFR_OKだったので問題ないと思いましたが、実際にはダメでした。
これは意外な盲点になるかもしれませんので、ご注意を。
まとめ
ffconf.hのFF_USE_CHMODを1にします。
ファイルパスは絶対パス(初期設定)の場合、ファイル名だけを与えます。
対象ファイルは閉じておかないとタイムスタンプが設定されない?
マイコンだと時刻情報としてRTCが必要になります。もし外付けするなら、DS3231が便利ですよ!
コメント