morimori
2015年10月3日 20時06分
お世話になっております、森下と申します。
シリアル通信で0x00が含まれるデータを送信すると0x00以降が送信されません。
3Byteの数値データを送ろうとしています。
どのようにしたら0x00も送ることができますでしょうか。
下記に「FAQ : シリアル通信をおこなうプログラムを作成するには?」
http://armadillo.atmark-techno.com/faq/serial-programming
をベースにしたソースを添付します。
下記のプログラムを実行するとシリアル通信のデバッグツールで受信すると
02 04 までしか受信できません。
どうかご教授のほどよろしくお願いいたします。
#include
#include
#include
#include
#include
#include
#define SERIAL_PORT "/dev/ttymxc1" /* シリアルインターフェースに対応するデバイスファイル */
#define BAUDRATE B19200
int main(int argc, char *argv[])
{
char buf[5]; /* バッファ */
int fd; /* ファイルディスクリプタ */
struct termios oldtio, newtio; /* シリアル通信設定 */
fd = open(SERIAL_PORT, O_RDWR); /* デバイスをオープンする */
ioctl(fd, TCGETS, &oldtio); /* 現在のシリアルポートの設定を待避させる */
newtio = oldtio; /* ポートの設定をコピー */
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
ioctl(fd, TCSETS, &newtio); /* ポートの設定を有効にする */
buf[0] = 0x02;
buf[1] = 0x04;
buf[2] = 0x00;
buf[3] = 0x06;
buf[4] = 0x03;
write(fd, buf, sizeof(buf)); /* デバイスへ5バイト書き込み */
ioctl(fd, TCSETS, &oldtio); /* ポートの設定を元に戻す */
close(fd); /* デバイスのクローズ */
return 0;
}
コメント
y.nakamura
中村です。
訂正です。すみません。
> ここで言っている「termios(3) に記述されている POSIX インタフェース」とは、
> 次のような関数です。
> int tcgetattr(int fd, struct termios *termios_p);
> int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
> int tcsendbreak(int fd, int duration);
> int tcdrain(int fd);
> int tcflush(int fd, int queue_selector);
> int tcflow(int fd, int action);
> void cfmakeraw(struct termios *termios_p);
> speed_t cfgetispeed(const struct termios *termios_p);
> speed_t cfgetospeed(const struct termios *termios_p);
> int cfsetispeed(struct termios *termios_p, speed_t speed);
> int cfsetospeed(struct termios *termios_p, speed_t speed);
> int cfsetspeed(struct termios *termios_p, speed_t speed);
termiosのmanをよく読まずにmanページからコピペしてしまいました。
次の2つはPOSIXでは規定されてないそうです。
void cfmakeraw(struct termios *termios_p);
int cfsetspeed(struct termios *termios_p, speed_t speed);
POSIX標準ではないですが、Linuxで使えます。
--
なかむら
morimori
y.nakamura
2015年10月3日 21時51分
中村です。
> ioctl(fd, TCGETS, &oldtio); /* 現在のシリアルポートの設定を待避させる */
> newtio = oldtio; /* ポートの設定をコピー */
> newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
> ioctl(fd, TCSETS, &newtio); /* ポートの設定を有効にする */
この部分を次のように変更してみてください。
(エラーチェックを省略していますが、チェックをするようにしてくださいね)
最後のtcsetattrの第2引数TCSAFLUSHは
TCSANOWでもいいかもしれません。
一応、これ(↓)も書いておきます。
man tty_ioctlから引用
ioctl を 使 用 す る と 移 植性のないプログラムになる。可能な場合は、
termios(3) に記述されている POSIX インタフェースを使うこと。
ここで言っている「termios(3) に記述されている POSIX インタフェース」とは、
次のような関数です。
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
int tcsendbreak(int fd, int duration);
int tcdrain(int fd);
int tcflush(int fd, int queue_selector);
int tcflow(int fd, int action);
void cfmakeraw(struct termios *termios_p);
speed_t cfgetispeed(const struct termios *termios_p);
speed_t cfgetospeed(const struct termios *termios_p);
int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);
int cfsetspeed(struct termios *termios_p, speed_t speed);
--
なかむら