raspberryPI3でSerialコンソールをOFFにしてプログラムからのシリアル入出力の実験をする。
前の記事https://ameblo.jp/fc2miha/entry-12833772813.htm
でSerialコンソールの実験をしましたが
普通のプログラムでテラタームを相手にしてtelnet風チャットのプログラムを作ろうと思いまして、
コンソールモードを無効にしたいと思ったんですが設定を元に戻すでもなく、試行錯誤したのでその記録です。
google先生で色々調べたんですが、これといった情報が見つからず、
最終的に判ったのが、raspbianの設定プログラム「LANG=C sudo raspi-config」を使う方法です。
このツールを使用して「9 Advanced Options」→「A8 Serial」→「No」と操作してRebootすると、
コンソールがOFFになって起動してきます。
この時の/boot//boot/cmdline.txtの状態は
「dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait」に変更されます。
同様に「/boot/config.txt」の最終行は
「dtoverlay=pi3-miniuart-bt」のまま
の状態です。
この状態で以下のプログラムを走らせると、ちゃんと漢字は漢字で送ってくれるみたいです。
すげー
プログラム
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
int main()
{
int fd;
fd_set readfds;
struct termios uartattr_save;
struct termios attr;
struct termios stdinattr;
fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY );
if (fd < 0) {
printf("serial open error¥n");
return -1;
}
tcgetattr(fd, &uartattr_save);
//attrの作成
// 115200bps
cfsetospeed(&attr, B115200);
cfmakeraw(&attr);
//uartのターミナルモードを設定する
// 8bit/STOPbit=1/flowOFF
attr.c_cflag |= CS8 | CLOCAL | CREAD;
attr.c_cc[VMIN] = 1; //最小文字数
attr.c_cc[VTIME] = 0; //タイムアウト時間
tcsetattr(fd, TCSANOW, &attr);
//stdinのターミナルモードを設定する
// カノニカルモード無効/ECHO-無効/CTRC-有効
tcgetattr(0, &stdinattr);
stdinattr.c_lflag &= ~ICANON;
stdinattr.c_lflag &= ~ECHO; // &= ~ISIG;
stdinattr.c_cc[VMIN] = 0; //最小文字数
stdinattr.c_cc[VTIME] = 0; //タイムアウト時間
tcsetattr(0, TCSANOW, &stdinattr);
//無限LOOP 終了する場合はCTRL+C
while (1) {
//FDを検査してstdinとuartのどちらかから入力があれば
char c;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(fd, &readfds);
int nActiveSelect = select(fd + 1, &readfds, 0, 0, 0);
if ( nActiveSelect ) {
//stdinの入力あり
if (FD_ISSET(0, &readfds)) {
//読み込んでuartへ書き出し
int nRead = read(0, &c, 1);
if ( nRead == 1) {
write(fd, &c, 1);
}
}
//uartの入力あり
if (FD_ISSET(fd, &readfds)) {
//読み込んでstdoutへ書き出し
int nRead = read(fd, &c, 1);
if ( nRead == 1) {
write(1, &c, 1);
}
}
}
}
//元に戻してclose
tcsetattr(fd, TCSANOW, &uartattr_save);
close(fd);
return 0;
}