LINUX RS232程式設計


Published on

LINUX RS232程式設計

Published in: Education
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

LINUX RS232程式設計

  1. 1. 9-1Chapter 9 Linux Serial ProgrammingArchitecturePort SettingsThe devices /dev/ttyS*All parameters can be easily configured from within a program. The configuration is stored in astructure struct termios, which is defined in <asm/termbits.h>:
  2. 2. 9-21. c_iflag handle all input processing, which means that the characters sent from the device can be processed before they are read with read.2. c_oflag handles the output processing. c_cflag contains the settings for the port, as the baudrate, bits per character, stop bits, etc..3. c_lflag determine if characters are echoed, signals are sent to your program, etc..4. c_cc defines the control characters for end of file, stop, etc.. Default values for the control characters are defined in <asm/termios.h>. Canonical Input ProcessingThis is the normal processing mode for terminals, which means that a read will only return afull line of input. A line is by default terminated by a NL (ASCII LF), an end of file, or an endof line character.
  3. 3. 9-3Canonical input processing can also handle the erase, delete word, and reprint characters,translate CR to NL, etc.. Non-Canonical Input ProcessingNon-Canonical Input Processing will handle a fixed amount of characters per read, andallows for a character timer. This mode should be used if your application will always read afixed number of characters, or if the connected device sends bursts of characters.在 Raw data (Non-Canonical) 的輸入程序模式下, 輸入的資料不會被組合成一行而輸入後的處理功能 (清除, 殺掉,刪除, 等等.) 都不能使用. 這個模式有兩個控制參數: c_cc[VTIME] 設定字元輸入時間計時器, 及 c_cc[VMIN] 設定滿足read(2)的最低字元接收個數.VMIN = 0 and VTIME = 0 This is a completely non-blocking read - the call is satisfied immediately directly from the drivers input queue. If data are available, its transferred to the callers buffer up to nbytes and returned. Otherwise zero is immediately returned to indicate "no data". Well note that this is "polling" of the serial port, and its almost always a bad idea. If done repeatedly, it can consume enormous amounts of processor time and is highly inefficient. Dont use this mode unless you really, really know what youre doing. 如 果 VMIN = 0 且 VTIME = 0, Non-bloking Read 模 式 , read(2) 立 即 Return 目 前 已 存 在 的 字 元 組 個 數 , 或 者 Return 0 表 示 沒 有 資 料 , 你 也 可 以 用 fcntl(uartfd, F_SETFL, FNDELAY); => 設 成 Nonlblocking ModeVMIN = 0 and VTIME > 0
  4. 4. 9-4 This is a pure timed read. If data are available in the input queue, its transferred to the callers buffer up to a maximum of nbytes, and returned immediately to the caller. Otherwise the driver blocks until data arrives, or when VTIME tenths expire from the start of the call. If the timer expires without data, zero is returned. A single byte is sufficient to satisfy this read call, but if more is available in the input queue, its returned to the caller. Note that this is an overall timer, not an intercharacter one. 如 果 VMIN = 0 且 VTIME > 0, VTIME 將 被 當 做 逾 時 設 定 值 . read(2) Return 的 情 況 為 讀 取 到 單 一 字 元 , 或 者 超 過 VTIME 所 定 義 的 時 間 (t =VTIME *0.1 s). 如 果 超 過 VTIME 所 定 義 的 時 間 , 則 不 會 傳 回 任 何 字 元 .VMIN > 0 and VTIME > 0 A read() is satisfied when either VMIN characters have been transferred to the callers buffer, or when VTIME tenths expire between characters. Since this timer is not started until the first character arrives, this call can block indefinitely if the serial line is idle. This is the most common mode of operation, and we consider VTIME to be an intercharactertimeout, not an overall one. This call should never return zero bytes read. 如 果 VMIN > 0 且 VTIME > 0, VTIME 將 被 當 做 接 收 字 元 間 隔 的 計 時 器 . read(2) Return 的 條 件 為 接 收 到 VMIN 個 數 的 字 元 , 或 兩 個 字 元 的 間 隔 時 間 超 過 VTIME 所 定 義 的 值 . 計 時 器 只 會 在 第 一 個 字 元 收 到 後 才 會 啟 動 . 且每讀到一個字元後會再重新計時.VMIN > 0 and VTIME = 0 This is a counted read that is satisfied only when at least VMIN characters have been transferred to the callers buffer - there is no timing component involved. This read can be satisfied from the drivers input queue (where the call could return immediately), or by waiting for new data to arrive: in this respect the call could block indefinitely. We believe that its undefined behavior if nbytes is less then VMIN. 如 果 VMIN > 0 且 VTIME = 0, VMIN 設 定 為 read(2) Return 的 最 低 字 元 接 收 個 數 . 由 於 TIME 是 零 , 所 以 計 時器將不被使用.
  5. 5. 9-5#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <stdio.h>/* baudrate settings are defined in <asm/termbits.h>, which isincluded by <termios.h> */#define BAUDRATE B38400/* change this definition for the correct port */#define MODEMDEVICE "/dev/ttyS1"#define _POSIX_SOURCE 1 /* POSIX compliant source */#define FALSE 0#define TRUE 1volatile int STOP=FALSE;
  6. 6. 9-6main(){ int fd,c, res; struct termios oldtio,newtio; char buf[255];/* Open modem device for reading and writing and not as controlling tty because we dont want to get killed if linenoise sends CTRL-C.*/ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* save current serial port settings */ bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings *//* BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. CRTSCTS : output hardware flow control (only used if the cable has
  7. 7. 9-7 all necessary lines. See sect. 7 of Serial-HOWTO) CS8 : 8n1 (8bit,no parity,1 stopbit) CLOCAL : local connection, no modem contol CREAD : enable receiving characters*/ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;/* IGNPAR : ignore bytes with parity errors ICRNL : map CR to NL (otherwise a CR input on the other computer will not terminate input) otherwise make device raw (no other input processing)*/ newtio.c_iflag = IGNPAR | ICRNL;/* Raw output.*/
  8. 8. 9-8 newtio.c_oflag = 0;/* ICANON : enable canonical input disable all echo functionality, and dont send signals to calling program*/ newtio.c_lflag = ICANON;/* initialize all control characters default values can be found in /usr/include/termios.h, and are given in the comments, but we dont need them here*/ newtio.c_cc[VINTR] = 0; /* Ctrl-c */ newtio.c_cc[VQUIT] = 0; /* Ctrl- */ newtio.c_cc[VERASE] = 0; /* del */ newtio.c_cc[VKILL] = 0; /* @ */ newtio.c_cc[VEOF] = 4; /* Ctrl-d */
  9. 9. 9-9 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */ newtio.c_cc[VSWTC] = 0; /* 0 */ newtio.c_cc[VSTART] = 0; /* Ctrl-q */ newtio.c_cc[VSTOP] = 0; /* Ctrl-s */ newtio.c_cc[VSUSP] = 0; /* Ctrl-z */ newtio.c_cc[VEOL] = 0; /* 0 */ newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */ newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */ newtio.c_cc[VWERASE] = 0; /* Ctrl-w */ newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */ newtio.c_cc[VEOL2] = 0; /* 0 *//* now clean the modem line and activate the settings for the port*/ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio);
  10. 10. 9-10/* terminal settings done, now handle input In this example, inputting a z at the beginning of a line will exit the program.*/ while (STOP==FALSE) { /* loop until we have a terminating condition */ /* read blocks program execution until a line terminating character is input, even if more than 255 chars are input. If the number of characters read is smaller than the number of chars available, subsequent reads will return the remaining chars. res will be set to the actual number of characters actually read */ res = read(fd,buf,255); buf[res]=0; /* set end of string, so we can printf */ printf(":%s:%dn", buf, res); if (buf[0]==z) STOP=TRUE; } /* restore the old port settings */
  11. 11. 9-11 tcsetattr(fd,TCSANOW,&oldtio);}