データロガーの実装を進めるに中って、boost を使うようになった。
そうすると、どうしても「システムコール」を実装しなくてはならない状況にな
った。
これは、boost の動作で、ファイルを操作したり、標準出力を使っている為なの
だと思うが、リンク時一連のシステムコールがリンクできずににエラーを起こす。
※boost の内部設定を変更して、それらを使わないように「魔改造」する事も考
えられるが、それはそれで、大変と思うので、とりあえず、標準的な設定で何と
かなるよにしたい。
以前にSH2Aで、LCDの描画などを行った時にも、同じような事があり、実
装したので、どうすれば良いか、簡単に説明しておこうと思う。
まず、最低限必要なのが、標準入出力のしくみなどだ。
以下の関数を最低限実装する必要があるようだ、何か足りなければ、リンクエラ
ーが出るので、その都度追加すればよい。
int open(const char *path, int flags, ...); int fstat(int file, struct stat *st); int read(int file, void *ptr, int len); int write(int file, const void *ptr, int len); int lseek(int file, int offset, int dir); int close(int file); int isatty(int file); void kill(int n, int m); int getpid(int n); void exit(int n);
また、固定のファイルディスクリプタとして以下がある:
stdin : 0 stdout : 1 stderr : 2
これらは、オープンもクローズもできない、また、シークも必要ない。
「write」、「read」の中で、「file」が0、1、2の場合に、シリアル入出力へ
繋げば良いと思う。
「isatty」は、ファイルディスクリプターが端末を参照しているかをチェックす
る機能なので、これも実装しておく。
※そうすれば、「printf」は使えるようになる。(ただ、C++ ではあくまでも、
iostream が基本なのと、自分の実装では、format があるので必要無い、又、
iostream を使うようなコードを書くと、単純にメモリーが足りなくて、リンク
時にエラーを起こすだけではある)
※とりあえず、この程度なら、RL78やR8Cでも利用可能と思う。
//-----------------------------------------------------------------// /*! @brief ファイル記述子で指定されたファイルから指定バイトを読む @param[in] file ファイル記述子 @param[in] ptr 読み込み先 @param[in] len 読み込みバイト数 @return 読み込みバイト数 */ //-----------------------------------------------------------------// int read(int file, void *ptr, int len) { int l = 0; if(file >= 0 && file <= 2) { // stdin if(file == 0) { char *p = ptr; for(int i = 0; i < len; ++i) { *p++ = sci_getch(); } errno = 0; l = len; } } return l; } //-----------------------------------------------------------------// /*! @brief ファイル記述子で指定されたファイルから指定バイトを書く @param[in] file ファイル記述子 @param[in] ptr 書き込み元 @param[in] len 書き込みバイト数 @return 書き込みバイト数 */ //-----------------------------------------------------------------// int write(int file, const void *ptr, int len) { int l = -1; if(file >= 0 && file <= 2) { if(file == 1 || file == 2) { const char *p = ptr; for(int i = 0; i < len; ++i) { char ch = *p++; sci_putch(ch); } l = len; errno = 0; } } return l; } //-----------------------------------------------------------------// /*! @brief ファイルディスクリプタが端末を参照しているかをチェックする @param[in] file ファイル記述子 @return 端末を参照するオープンされたファイルディスクリプタ @n であれば 1 を返す。@n そうでなければ 0 を返し、 errno にエラーを示す値を設定する。 */ //-----------------------------------------------------------------// int isatty(int file) { if(file >= 0 && file <= 2) { errno = 0; return 1; } else if(file < OPEN_MAX_) { errno = ENOTTY; return 0; } errno = EINVAL; return 0; }
--------
FatFs を使って、SDカードにアクセスする場合は、GitHub の syscalls.cを参照してほしい。
RX24Tの場合、RAMは16Kしか無いので、記憶割り当てを実装するのは、
少しキビシイ、そこで、FatFsの設定では、「記憶割り当て」を使わない設
定にしている、そうすると、1個のファイルを開くのに必要なメモリーは、そこ
そこ大きく、最大オープン数を多く取るとスタテックにメモリーを消費する。
ファイルの先頭で、「OPEN_MAX_」を「4」と定義してある。
最大4つまでファイルを開く事ができる、通常これくらいあれば十分と思うが、
アプリにより最適な値を調整する必要があるかもしれない。
又、FatFSを使わない場合には、「FAT_FS」をコメントアウトして、
無効にする。
ファイルをオープンするパスは、UTF-8を使う、内部でShift_JIS
に変換されて、FatFSに渡される。
FatFsを使う場合、内部で「sdc_io」クラスと連携しているので、SDカード
の自動マウントなどを見守る必要がある。