マイコンで、シリアルポートとは別に、キャラLCDとかにprintf経由で文字列を出したかった。
_open
システムコールの_open_rからLCDのファイルディスクリプタを返す。
int _open_r(struct _reent *r, const char *file, int flags, int mode)
{
if (!strcmp(file, "CLCD"))
{
return (3);
}
return (-1);
}
_write
CLCDのディスクリプタが来た場合はCLCDにputcする。
if (file == 3)
{
int i;
for (i = 0; i < len; ++i)
{
lcd_putc(p[i]);
}
return (i);
}
_lseek
カーソルの移動くらいはやりたい。
printfからエスケープシーケンスを出すと、write側でうまく処理しなきゃいけないので面倒。fseekで対応する。
if (file == 3)
{
lcd_locate(ptr >> 8 & 0xFF, ptr & 0xFF);
return (0);
}
使い方
こんな感じ。
FILE *clcd = fopen("CLCD", "w");
fprintf(clcd, "Hello World!!\n"
"ABCdef123");
fseek(clcd, 0x00'0E, SEEK_SET);
fprintf(clcd, "*");
fseek(clcd, 0x01'0D, SEEK_SET);
fprintf(clcd, "#");
今回はマイコンリセットするまで(つまり半永久的に)clcdを使うのでfcloseはしてないけど、普通はそのあたりをしっかり対応する必要がある(今回は面倒なのでやらなかった)。
その他
strcmp使うの久しぶりすぎてif (strcmp(file, "CLCD"))
ってやっててハングアップするのにかなり時間食われた。。。_openで-1が帰るのでFILE*がヌルポになってた。
最初、FILE構造体のint _file
だけテキトーに設定すればいいや、と思っていろいろ試したけど、うまく動かなかった。
今回はファイルディスクリプタの数値をベタ書きしてるけど、いわずもがな定数とか使うべき。