串口linux编程,linux串口通信编程

#include #define UART_NAME "/dev/ttyS0"

static int g_quit;

static int g_speed;

static void handle_signal(int sig)

{

if (SIGINT == sig || SIGTERM == sig)

g_quit = 1;

}

static struct sigaction sigact = {

.sa_handler = handle_signal,

};

static struct option longopts[] = {

{"help", no_argument, NULL, 'h'},

{"baudrate", required_argument, NULL, 'r'},

{0, 0, 0, 0},

};

static void print_usage(void)

{

fprintf(stdout, "usage:\n");

fprintf(stdout, "\t-r | --baudrate the serial baud rate\n");

fprintf(stdout, "\t-h | --help show this help and exit\n");

}

static int parse_arg(int argc, char **argv)

{

int ret = 0;

char c = '0';

while (

(c = getopt_long(argc, argv, "-:r:h", longopts, NULL))

!= -1) {

switch (c) {

case 'r':

g_speed = atoi(optarg);

break;

case 'h':

ret = -1;

break;

case ':':

fprintf(stdout, "%c require argument\n", optopt);

ret = -1;

break;

case '?':

fprintf(stdout, "%c invalid argument\n", optopt);

ret = -1;

break;

default:

break;

}

}

return ret;

}

static int uart_open(char *filename)

{

int fd;

//fd = open(filename, O_RDWR);

fd = open(filename, O_RDWR|O_NOCTTY|O_NDELAY);

if (fd < 0) {

printf("%s %d: failed to open output file\n",

__FILE__, __LINE__);

return -1;

}

//nonblock

if (fcntl(fd, F_SETFL, 0) < 0) {

printf("fcntl failed\n");

close(fd);

return -1;

}

return fd;

}

static int uart_set(int fd, int speed, int flow_ctrl,

int databits, int parity, int stopbits)

{

struct termios options;

int ret = 0;

if (tcgetattr(fd, &options) != 0) {

printf("Setup serial fialed!\n");

return -1;

}

int i;

int speed_arr[] = {B1500000, B1152000, B1000000, B921600,

B576000, B500000, B460800, B230400, B115200, B57600,

B38400, B19200, B9600, B4800, B2400, B1800, B1200,

B600, B300, B200, B150, B134, B110, B75, B50, B0};

int name_arr[] = {1500000, 1152000, 1000000, 921600,

576000, 500000, 460800, 230400, 115200, 57600,

38400, 19200, 9600, 4800, 2400, 1800, 1200,

600, 300, 200, 150, 134, 110, 75, 50, 0};

if (tcgetattr(fd, &options) != 0) {

printf("Setup serial fialed!\n");

return -1;

}

printf("speed = %d\n", speed);

for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {

if (speed == name_arr[i]) {

ret = cfsetispeed(&options, speed_arr[i]);

if (ret) {

perror("cfsetispeed");

printf("set in speed failed\n");

}

ret = cfsetospeed(&options, speed_arr[i]);

if (ret) {

perror("cfsetispeed");

printf("set out speed failed\n");

}

break;

}

}

options.c_cflag |= CLOCAL;

options.c_cflag |= CREAD;

switch (flow_ctrl) {

case 0: // no flow control

options.c_cflag &= ~CRTSCTS;

break;

case 1: // hardware flow control

options.c_cflag |= CRTSCTS;

break;

case 2: //software flow control

options.c_cflag |= IXON|IXOFF|IXANY;

break;

default:

printf("Unsupported flow control\n");

return -1;

}

options.c_cflag &= ~CSIZE;

switch (databits) {

case 5:

options.c_cflag |= CS5;

break;

case 6:

options.c_cflag |= CS6;

break;

case 7:

options.c_cflag |= CS7;

break;

case 8:

options.c_cflag |= CS8;

break;

default:

printf("Unsupported databits!\n");

return -1;

}

switch (parity) {

case 'n': //no parity

case 'N':

options.c_cflag &= ~PARENB;

options.c_iflag &= ~INPCK;

break;

case 'o': //odd parity

case 'O':

options.c_cflag |= (PARODD | PARENB);

options.c_iflag &= INPCK;

break;

case 'e': //even parity

case 'E':

options.c_cflag |= PARENB;

options.c_cflag &= ~PARODD;

options.c_iflag |= INPCK;

break;

case 's': //blank

case 'S':

options.c_cflag &= ~PARENB;

options.c_iflag &= ~CSTOPB;

break;

default:

printf("Unsupported parity\n");

return -1;

}

switch (stopbits) {

case 1:

options.c_cflag &= ~CSTOPB;

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

printf("Unsupported stop bits\n");

return -1;

}

//mode

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/

options.c_oflag &= ~OPOST; /*Output*/

//wait_time: 0.1s; min char to read:1

options.c_cc[VTIME] = 1;

options.c_cc[VMIN] = 1;

//if data overflow, receive data, but not read

tcflush(fd, TCIFLUSH);

//save configuration

if (tcsetattr(fd, TCSANOW, &options) != 0) {

printf("set serial error!\n");

return -1;

}

return 0;

}

static int recv_data(int fd, int fdtest)

{

int inflg = 0;

int ret, size;

int *data = NULL;

do {

if (g_quit)

break;

inflg = 0;

ret = 0;

size = 0;

int hsize = read(fd, &size, 4);

if (hsize < 0) {

printf("read header size error\n");

ret = -1;

break;

}

if (size <= 0)

continue;

printf("size = %d\n", size);

if (data) {

free(data);

data = NULL;

}

data = calloc(1, size);

if (!data) {

printf("calloc failed\n");

ret = -1;

break;

}

int len = 0;

int left_size = size - len;

do {

len = read(fd, data, left_size);

if (len < 0) {

printf("read fd error\n");

ret = -1;

break;

}

//printf("real read size = %d\n", len);

int n = write(fdtest, data, len);

if (n < 0) {

printf("write error!\n");

ret = -1;

break;

}

left_size = left_size - len;

} while (left_size > 0);

inflg = 1;

} while (!inflg);

if (data) {

free(data);

data = NULL;

}

return ret;

}

int main(int argc, char **argv)

{

int ret = 0;

int fd, fdtest;

char send[1] = {'a'};

ret = sigaction(SIGINT, &sigact, NULL);

ret |= sigaction(SIGTERM, &sigact, NULL);

if (ret) {

printf("%s line%d: %s\n",

__FILE__, __LINE__, strerror(errno));

return -1;

}

g_speed = 9600;

ret = parse_arg(argc, argv);

if (ret) {

print_usage();

return -1;

}

fd = uart_open("/dev/ttyS0");

if (fd < 0)

return -1;

int speed = g_speed;

int flow_ctrl = 0;

int databits = 8;

int stopbits = 1;

int parity = 'O';

ret = uart_set(fd, speed, flow_ctrl, databits, parity, stopbits);

if (ret) {

printf("uart_set failed\n");

goto out;

}

fdtest = open("/mnt/recv.h264", O_RDWR|O_SYNC);

if (fdtest < 0) {

printf("open fdtest failed\n");

goto out;

}

int n = write(fd, send, 1);

if (n <= 0) {

printf("send a failed\n");

close(fdtest);

goto out;

}

do {

if (g_quit)

break;

ret = recv_data(fd, fdtest);

usleep(1000*10);

send[0] = 'b';

int res = write(fd, send, 1);

if (res < 0)

break;

/* printf("%s: %s: %d\n", __FILE__, __func__, __LINE__); */

} while (!ret);

close(fdtest);

out:

close(fd);

return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值