データロガーの実装を進めるに中って、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カード
の自動マウントなどを見守る必要がある。