3 \brief
\83V
\83\8a\83A
\83\8b\92Ê
\90M (Linux, Mac
\8eÀ
\91\95)
5 Serial Communication Interface
\90§
\8cä
8 \author Satofumi KAMIMURA
10 $Id: serial_ctrl_lin.c 1559 2009-12-01 13:13:08Z satofumi $
13 #include "serial_errno.h"
14 #include "ring_buffer.h"
34 void serial_initialize(serial_t *serial)
36 serial->fd_ = InvalidFd;
37 serial->errno_ = SerialNoError;
38 serial->has_last_ch_ = False;
40 ring_initialize(&serial->ring_, serial->buffer_, RingBufferSizeShift);
45 int serial_connect(serial_t *serial, const char *device, long baudrate)
50 serial_initialize(serial);
53 enum { O_EXLOCK = 0x0 }; /* Linux
\82Å
\82Í
\8eg
\82¦
\82È
\82¢
\82Ì
\82Å
\83_
\83~
\81[
\82ð
\8dì
\90¬
\82µ
\82Ä
\82¨
\82 */
55 serial->fd_ = open(device, O_RDWR | O_EXLOCK | O_NONBLOCK | O_NOCTTY);
56 if (serial->fd_ < 0) {
57 /*
\90Ú
\91±
\82É
\8e¸
\94s */
58 strerror_r(errno, serial->error_string_, SerialErrorStringSize);
59 return SerialConnectionFail;
62 flags = fcntl(serial->fd_, F_GETFL, 0);
63 fcntl(serial->fd_, F_SETFL, flags & ~O_NONBLOCK);
65 /*
\83V
\83\8a\83A
\83\8b\92Ê
\90M
\82Ì
\8f\89\8aú
\89» */
66 tcgetattr(serial->fd_, &serial->sio_);
67 serial->sio_.c_iflag = 0;
68 serial->sio_.c_oflag = 0;
69 serial->sio_.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
70 serial->sio_.c_cflag |= CS8 | CREAD | CLOCAL;
71 serial->sio_.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN);
73 serial->sio_.c_cc[VMIN] = 0;
74 serial->sio_.c_cc[VTIME] = 0;
76 /*
\83{
\81[
\83\8c\81[
\83g
\82Ì
\95Ï
\8dX */
77 ret = serial_setBaudrate(serial, baudrate);
82 /*
\83V
\83\8a\83A
\83\8b\90§
\8cä
\8d\
\91¢
\91Ì
\82Ì
\8f\89\8aú
\89» */
83 serial->has_last_ch_ = False;
90 void serial_disconnect(serial_t *serial)
92 if (serial->fd_ >= 0) {
94 serial->fd_ = InvalidFd;
99 int serial_isConnected(const serial_t *serial)
101 return ((serial == NULL) || (serial->fd_ == InvalidFd)) ? 0 : 1;
105 /*
\83{
\81[
\83\8c\81[
\83g
\82Ì
\90Ý
\92è */
106 int serial_setBaudrate(serial_t *serial, long baudrate)
108 long baudrate_value = -1;
112 baudrate_value = B4800;
116 baudrate_value = B9600;
120 baudrate_value = B19200;
124 baudrate_value = B38400;
128 baudrate_value = B57600;
132 baudrate_value = B115200;
136 return SerialSetBaudrateFail;
139 /*
\83{
\81[
\83\8c\81[
\83g
\95Ï
\8dX */
140 cfsetospeed(&serial->sio_, baudrate_value);
141 cfsetispeed(&serial->sio_, baudrate_value);
142 tcsetattr(serial->fd_, TCSADRAIN, &serial->sio_);
143 serial_clear(serial);
150 int serial_send(serial_t *serial, const char *data, int data_size)
152 if (! serial_isConnected(serial)) {
153 return SerialConnectionFail;
155 return write(serial->fd_, data, data_size);
159 static int waitReceive(serial_t* serial, int timeout)
164 //
\83^
\83C
\83\80\83A
\83E
\83g
\90Ý
\92è
166 FD_SET(serial->fd_, &rfds);
168 tv.tv_sec = timeout / 1000;
169 tv.tv_usec = (timeout % 1000) * 1000;
171 if (select(serial->fd_ + 1, &rfds, NULL, NULL,
172 (timeout < 0) ? NULL : &tv) <= 0) {
173 /*
\83^
\83C
\83\80\83A
\83E
\83g
\94
\90¶ */
180 static int internal_receive(char data[], int data_size_max,
181 serial_t* serial, int timeout)
185 if (data_size_max <= 0) {
189 while (filled < data_size_max) {
193 if (! waitReceive(serial, timeout)) {
197 require_n = data_size_max - filled;
198 read_n = read(serial->fd_, &data[filled], require_n);
200 /*
\93Ç
\82Ý
\8fo
\82µ
\83G
\83\89\81[
\81B
\8c»
\8dÝ
\82Ü
\82Å
\82Ì
\8eó
\90M
\93à
\97e
\82Å
\96ß
\82é */
210 int serial_recv(serial_t *serial, char* data, int data_size_max, int timeout)
216 if (data_size_max <= 0) {
220 /*
\8f\91\82«
\96ß
\82µ
\82½
\82P
\95¶
\8e\9a\82ª
\82 \82ê
\82Î
\81A
\8f\91\82«
\8fo
\82· */
222 if (serial->has_last_ch_ != False) {
223 data[0] = serial->last_ch_;
224 serial->has_last_ch_ = False;
228 if (! serial_isConnected(serial)) {
232 return SerialConnectionFail;
235 buffer_size = ring_size(&serial->ring_);
236 read_n = data_size_max - filled;
237 if (buffer_size < read_n) {
238 //
\83\8a\83\93\83O
\83o
\83b
\83t
\83@
\93à
\82Ì
\83f
\81[
\83^
\82Å
\91«
\82è
\82È
\82¯
\82ê
\82Î
\81A
\83f
\81[
\83^
\82ð
\93Ç
\82Ý
\91«
\82·
239 char buffer[RingBufferSize];
240 int n = internal_receive(buffer,
241 ring_capacity(&serial->ring_) - buffer_size,
243 ring_write(&serial->ring_, buffer, n);
245 buffer_size = ring_size(&serial->ring_);
247 //
\83\8a\83\93\83O
\83o
\83b
\83t
\83@
\93à
\82Ì
\83f
\81[
\83^
\82ð
\95Ô
\82·
248 if (read_n > buffer_size) {
249 read_n = buffer_size;
252 ring_read(&serial->ring_, &data[filled], read_n);
256 //
\83f
\81[
\83^
\82ð
\83^
\83C
\83\80\83A
\83E
\83g
\95t
\82«
\82Å
\93Ç
\82Ý
\8fo
\82·
257 filled += internal_receive(&data[filled],
258 data_size_max - filled, serial, timeout);
263 /*
\82P
\95¶
\8e\9a\8f\91\82«
\96ß
\82· */
264 void serial_ungetc(serial_t *serial, char ch)
266 serial->has_last_ch_ = True;
267 serial->last_ch_ = ch;
271 void serial_clear(serial_t* serial)
273 tcdrain(serial->fd_);
274 tcflush(serial->fd_, TCIOFLUSH);
275 ring_clear(&serial->ring_);
276 serial->has_last_ch_ = False;