文档库 最新最全的文档下载
当前位置:文档库 › serial_cr_nl

serial_cr_nl

ref https://www.wendangku.net/doc/a72245597.html,/~mike/serial/serial.html

1.open
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);

extra flag when opening:
NOCTTY : tells that this program doesn't want to be the "controlling terminal" for that port.
O_NDELAY: tells process DO NOT sleep until the DCD signal line is the space voltage.

2. reading , block / non-block
//set block none-block mode
fcntl(fd, F_SETFL, FNDELAY);//non-block
fcntl(fd, F_SETFL, 0);//block

3.close, close as file
close(fd);

4.set parameter
struct termios options;
tcsetattr(fd, TCSANOW, &options);

Termios Structure Members:
c_cflag Control options
c_lflag Line options
c_iflag Input options
c_oflag Output options
c_cc Control characters
c_ispeed Input baud (new interface)
c_ospeed Output baud (new interface)

always use the bitwise AND, OR, and NOT operators to set or clear bits in the members

opitional flags for tcsetattr():
TCSANOW Make changes now without waiting for data to complete
TCSADRAIN Wait until everything has been transmitted
TCSAFLUSH Flush input and output buffers and make the change

4.set the baud rate.
using posix interface install of the the flag, as older interface store speed in c_cflag, while new interface stored in
c_ispeed/ c_ospeed , use api to set the baud rate instead of set the flag directly.
cfsetospeed()
cfsetispeed()

5.set Parity Check
No parity (8N1):
options.c_cflag &= ~PARENB
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

Even parity (7E1):
options.c_cflag |= PARENB
options.c_cflag &= ~PARODD
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;

Odd parity (7O1):
options.c_cflag |= PARENB
options.c_cflag |= PARODD
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;

Space parity is setup the same as no parity (7S1):
options.c_cflag &= ~PARENB
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

6.Choosing Canonical/RAW Input
Input characters are put into a buffer which can be edited interactively by the user until a CR (carriage return)
or LF (line feed) character is received
options.c_lflag |= (ICANON | ECHO | ECHOE);

RAW input:
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

7.Setting Software Flow Control
XON(ctrl+q) XOFF(ctrl+s) default used as control char, if need to transfer it, set the flag to disale it.
Opt.c_iflag &= ~ (IXON | IXOFF | IXANY);

8.disable cr-nl mapping
Opt.c_iflag &= ~ (INLCR | ICRNL | IGNCR);
Opt.c_oflag &= ~(ONLCR | OCRNL);

9.ioctl functions and posix functions
Most ioctl functions could be done via posix functions, except
TIOCMGET Returns the state of the "MODEM" bits. None
TIOCMSET Sets the state of the "MODEM" bits. None
FIONREAD Returns the number of bytes in the input buffer. None

a. get status bits
int fd;
int status;
ioctl(fd, TIOCMGET, &status);
b.

set status bits
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
c. get bytes avialable to read:
int bytes;
ioctl(fd, FIONREAD, &bytes);
this could be done more genearylly via select() function:

read/write sample:
#include
#include /* Standard input/output definitions */
#include /* String function definitions */
#include /* UNIX standard function definitions */
#include /* File control definitions */
#include /* Error number definitions */
#include /* POSIX terminal control definitions */
#include
#include
#include
using namespace std;

struct termios stdidefios;

void loop(int);
void setPortAttr(int fd, int speed);
void setSTDIAttr();

int openCommPort(const char* pttysrc) {
return open(pttysrc, O_RDWR | O_NOCTTY | O_NDELAY);
}

void resetSTDIAttr() {
tcsetattr(STDIN_FILENO, TCSANOW, &stdidefios);
}

int main(int argc, char* argv[]) {
if(argc < 1) {
printf("PLS specify the devices.");
return 0;
}
const char* pdevice = argv[1];
int fd_serialport = openCommPort(pdevice);
if (fd_serialport == -1) {
printf("Unable to open port %s .\n",pdevice);
return 0;
} else {
printf("Opened the port %s .\n",pdevice);
}

setPortAttr(fd_serialport, B115200);
setSTDIAttr();
loop(fd_serialport);

close(fd_serialport);
resetSTDIAttr();
return 0;
}

void setPortAttr(int fd, int speed) {
fcntl(fd, F_SETFL, 0); //0 block mode

struct termios options;
tcgetattr(fd, &options);

//set baud rate
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);

options.c_cflag |= (CLOCAL | CREAD);
//options.c_cflag &= ~CLOCAL;

options.c_cflag &= ~PARENB; //disable parity bit
options.c_cflag &= ~CSTOPB; //none stop bits

options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8; //8 data bits

//options.c_iflag &= ~(IGNCR | ICRNL | IGNCR);//cr-nl mapping
//options.c_oflag &= ~(ONLCR | OCRNL);

options.c_cflag &= ~(CRTSCTS);
options.c_iflag &= ~(IXON | IXOFF | IXANY);

options.c_iflag |= (INPCK | ISTRIP);
//options.c_lflag |= (ICANON | ECHO | ECHOE);//canonical mode
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw mode

tcsetattr(fd, TCSANOW, &options);
}
void setSTDIAttr() {
struct termios options;
tcgetattr(STDIN_FILENO, &options);
stdidefios = options;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//turn off echo and run in raw mode
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &options);
}

void loop(int fd) {
fd_set rdset, wrset;
deque vc;

while (true) {
FD_ZERO(&rdset);
FD_ZERO(&wrset);

FD_SET(STDIN_FILENO, &rdset);
FD_SET(fd, &rdset);

if (vc.size() > 0) {
FD_SET(fd, &wrset);
}

struct timeval tv;
https://www.wendangku.net/doc/a72245597.html,_sec = 8;
https://www.wendangku.net/doc/a72245597.html,_usec = 0;

int slcresult = 0;
if ((

slcresult = select(fd + 1, &rdset, &wrset, NULL, &tv)) < 0) {
printf("select failed: %d : %s \n", errno, strerror(errno));
} else if (slcresult == 0) {
//select time out
} else {
unsigned char c;
int n = 0;

if (FD_ISSET(STDIN_FILENO, &rdset)) {
//STDI read
do {
n = read(STDIN_FILENO, &c, 1);
} while (n < 0 && errno == EINTR);

if (n > 0) {

if(c == 0x01) {//ctrl+a to exit the loop
break;
}
if (c != '\r' && c != '\n') {
vc.push_back(c);
} else {
vc.push_back('\r');
}
}
}

if (FD_ISSET(fd, &rdset)) {
//data read
do {
n = read(fd, &c, 1);
} while (n < 0 && errno == EINTR);

if (n > 0) {
printf("%c", c);
//write(STDOUT_FILENO, &c, 1);
fflush(stdout);
}
}

if (FD_ISSET(fd, &wrset)) {
//data write
int count = 0;
while (vc.size() > 0) {
unsigned char uc = vc.front();
vc.pop_front();
do {
n = write(fd, &uc, 1);
} while (n < 0 && errno == EINTR);
count += n;
}
}
}
}

}

相关文档