3 * @author Shinichiro Nakamura
4 * @brief シリアルポートドライバの実装。(Linuxプラットフォーム用)
8 * ===============================================================
9 * Serial interface library
11 * ===============================================================
12 * Copyright (c) 2010-2012 Shinichiro Nakamura
14 * Permission is hereby granted, free of charge, to any person
15 * obtaining a copy of this software and associated documentation
16 * files (the "Software"), to deal in the Software without
17 * restriction, including without limitation the rights to use,
18 * copy, modify, merge, publish, distribute, sublicense, and/or
19 * sell copies of the Software, and to permit persons to whom the
20 * Software is furnished to do so, subject to the following
23 * The above copyright notice and this permission notice shall be
24 * included in all copies or substantial portions of the Software.
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
28 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
30 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
31 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 * ===============================================================
44 #include <sys/types.h>
51 #define MUTEX_INIT() pthread_mutex_init(&(s->mutex), NULL)
52 #define MUTEX_LOCK() pthread_mutex_lock(&(s->mutex))
53 #define MUTEX_UNLOCK() pthread_mutex_unlock(&(s->mutex))
58 struct termios termios_old;
59 struct termios termios_new;
60 pthread_mutex_t mutex;
66 * @param devfile シリアルポートのデバイスファイル名.
72 SERIAL *serial_open(const char *devfile, const enum SerialBaud baud)
77 * シリアルデスクリプタの管理領域を確保する.
79 SERIAL *s = (SERIAL *) malloc(sizeof(SERIAL));
92 strcpy(s->devfile, devfile);
93 s->fd = open(devfile, O_RDWR | O_NOCTTY | O_NDELAY);
102 tcgetattr(s->fd, &(s->termios_old));
107 memset(&(s->termios_new), 0x00, sizeof(s->termios_new));
110 * Bxxxxx : ボーレートの設定.cfsetispeed と cfsetospeed も使用できる
111 * CS8 : 8n1 (8 ビット,ノンパリティ,ストップビット 1)
112 * CLOCAL : ローカル接続,モデム制御なし
113 * CREAD : 受信文字(receiving characters)を有効にする
115 s->termios_new.c_cflag = CS8 | CLOCAL | CREAD;
118 s->termios_new.c_cflag |= B2400;
122 s->termios_new.c_cflag |= B4800;
126 s->termios_new.c_cflag |= B9600;
129 case SerialBaud19200:
130 s->termios_new.c_cflag |= B19200;
133 case SerialBaud38400:
134 s->termios_new.c_cflag |= B38400;
138 s->termios_new.c_cflag |= B9600;
142 cfsetispeed(&(s->termios_new), baudrate);
143 cfsetospeed(&(s->termios_new), baudrate);
146 * IGNPAR : パリティエラーのデータは無視する
148 s->termios_new.c_iflag = IGNPAR;
153 s->termios_new.c_oflag = 0;
156 * 入力モードをノンカノニカル、ノンエコーに設定する
158 s->termios_new.c_lflag = 0;
161 * モデムラインをクリアし,ポートの設定を有効にする
163 tcflush(s->fd, TCIFLUSH);
164 tcsetpgrp(s->fd, getpgrp());
165 tcsetattr(s->fd, TCSANOW, &(s->termios_new));
173 * @param s シリアルデスクリプタへのポインタ.
177 int serial_close(SERIAL * s)
182 tcsetattr(s->fd, TCSANOW, &(s->termios_old));
190 * シリアルデスクリプタの管理領域を破棄する.
198 * シリアルポートから指定バイト数の読み込みを実行する.
200 * @param s シリアルデスクリプタへのポインタ.
201 * @param buf バッファへのポインタ.
202 * @param size 読み込みバイト数.
206 int serial_read(SERIAL * s, unsigned char *buf, const size_t size)
216 while (rcvcnt < size) {
217 int r = read(s->fd, buf + rcvcnt, size - rcvcnt);
231 * シリアルポートから指定バイト数の読み込みを実行する.
233 * @param s シリアルデスクリプタへのポインタ.
234 * @param buf バッファへのポインタ.
235 * @param size 読み込みバイト数.
236 * @param ms ミリ秒単位のタイムアウト時間.
240 int serial_read_with_timeout(SERIAL * s,
241 unsigned char *buf, const size_t size, const int ms)
249 * タイムアウトを設定して読み込みを実行する.
251 for (i = 0; i < (int) size; i++) {
256 if (fds.revents & POLLIN) {
260 int r = read(s->fd, buf + i, 1);
280 * シリアルポートへ指定バイト数の書き込みを実行する.
282 * @param s シリアルデスクリプタへのポインタ.
283 * @param buf バッファへのポインタ.
284 * @param size 書き込みバイト数.
288 int serial_write(SERIAL * s,
289 const unsigned char *buf, const size_t size)
296 while (sndcnt < size) {
297 int r = write(s->fd, buf + sndcnt, size - sndcnt);