/* uart_tx.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <termios.h>
#define TEST_LEN (1024 * 400)
static char *dev_name = "/dev/ttyS2";
static int baud_rate = 9600;
static struct option opts[] = {
{"device", required_argument, NULL, 'd'},
{"baud", required_argument, NULL, 'b'},
{"help", no_argument, NULL, 'h'},
};
static void parse_cmd(int argc, char *argv[])
{
int ch;
while ((ch = getopt_long(argc, argv, "d:b:l:h", opts, NULL)) != -1) {
switch (ch) {
case 'd':
//printf("dev_name: %s\n", optarg);
dev_name = optarg;
break;
case 'b':
//printf("baud_rate: %s\n", optarg);
baud_rate = atoi(optarg);
break;
case 'h':
printf("Usage: %s -d dev_name -b baud_rate\n", argv[0]);
printf("like:\n");
printf("\t %s -d /dev/ttyS2\n", argv[0]);
printf("\t %s --device /dev/ttyS2 -b 9600\n", argv[0]);
break;
default:
printf("Unknown option or invalid format!\n");
printf("Pls: %s --help for more info\n", argv[0]);
break;
}
}
}
int set_serial(int fd, int baud_rate, int nBits, char nEvent, int nStop)
{
struct termios tty_cfg;
memset(&tty_cfg, 0, sizeof(tty_cfg));
tty_cfg.c_cflag |= (CLOCAL|CREAD); /* CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 */
tty_cfg.c_cflag &= ~CSIZE; /* 设置数据位 */
switch(baud_rate) {
case 2400:
cfsetispeed(&tty_cfg, B2400);
cfsetospeed(&tty_cfg, B2400);
break;
case 4800:
cfsetispeed(&tty_cfg, B4800);
cfsetospeed(&tty_cfg, B4800);
break;
case 9600:
cfsetispeed(&tty_cfg, B9600);
cfsetospeed(&tty_cfg, B9600);
break;
case 115200:
cfsetispeed(&tty_cfg, B115200);
cfsetospeed(&tty_cfg, B115200);
break;
case 460800:
cfsetispeed(&tty_cfg, B460800);
cfsetospeed(&tty_cfg, B460800);
break;
default:
cfsetispeed(&tty_cfg, B9600);
cfsetospeed(&tty_cfg, B9600);
break;
}
switch(nBits) {
case 7:
tty_cfg.c_cflag |= CS7;
break;
case 8:
tty_cfg.c_cflag |= CS8;
break;
}
switch(nEvent) {
case '0': /* 奇校验 */
tty_cfg.c_cflag |= PARENB; /* 开启奇偶校验 */
tty_cfg.c_iflag |= (INPCK | ISTRIP); /*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特 */
tty_cfg.c_cflag |= PARODD; /*启用奇校验(默认为偶校验)*/
break;
case 'E': /*偶校验*/
tty_cfg.c_cflag |= PARENB; /*开启奇偶校验 */
tty_cfg.c_iflag |= ( INPCK | ISTRIP); /*打开输入奇偶校验并去除字符第八个比特*/
tty_cfg.c_cflag &= ~PARODD; /*启用偶校验*/
break;
case 'N': /*无奇偶校验*/
tty_cfg.c_cflag &= ~PARENB;
break;
}
/* 设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB */
if(nStop == 1)
tty_cfg.c_cflag &= ~CSTOPB; /*默认为一位停止位; */
else if( nStop == 2)
tty_cfg.c_cflag |= CSTOPB; /* CSTOPB表示送两位停止位 */
/* flow control option */
tty_cfg.c_cflag |= CRTSCTS;
/* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/
tty_cfg.c_cc[VTIME] = 0; /* 非规范模式读取时的超时时间;*/
tty_cfg.c_cc[VMIN] = 0; /* 非规范模式读取时的最小字符数*/
tcflush(fd, TCIFLUSH); /* tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
/*激活配置使其生效*/
if((tcsetattr(fd, TCSANOW, &tty_cfg)) != 0) {
printf("com set error");
exit(1);
}
return 0;
}
char buff[TEST_LEN];
int main(int argc, char *argv[])
{
int fd=0;
int cnt=0;
int sum=0;
static int num=0;
char *p=NULL;
parse_cmd(argc, argv);
printf("TX: dev_name=%s, baud_rate=%d\n", dev_name, baud_rate);
fd = open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < 0) {
printf("Can't Open %s\n", dev_name);
return -1;
}
set_serial(fd, baud_rate, 8, 'N', 1);
sleep(1);
memset(buff, 0x55, TEST_LEN);
//printf("start send: %ds\n", time(NULL));
p = &buff[0];
while(1) {
cnt = write(fd, p, (TEST_LEN-sum));
if(cnt < 0) {
//sleep(1);
continue;
}
sum += cnt;
if(sum >= TEST_LEN)
break;
p += cnt;
printf("TX%d: cnt = %d, sum = %d\n", num++, cnt, sum);
}
printf("send %d: %ds\n", sum, time(NULL));
close(fd);
return 0;
}
/* uart_rx.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <termios.h>
#define TEST_LEN (1024 * 400)
static char *dev_name = "/dev/ttyS2";
static int baud_rate = 9600;
static struct option opts[] = {
{"device", required_argument, NULL, 'd'},
{"baud", required_argument, NULL, 'b'},
{"help", no_argument, NULL, 'h'},
};
static void parse_cmd(int argc, char *argv[])
{
int ch;
while ((ch = getopt_long(argc, argv, "d:b:l:h", opts, NULL)) != -1) {
switch (ch) {
case 'd':
//printf("dev_name: %s\n", optarg);
dev_name = optarg;
break;
case 'b':
//printf("baud_rate: %s\n", optarg);
baud_rate = atoi(optarg);
break;
case 'h':
printf("Usage: %s -d dev_name -b baud_rate\n", argv[0]);
printf("like:\n");
printf("\t %s -d /dev/ttyS2\n", argv[0]);
printf("\t %s --device /dev/ttyS2 -b 9600\n", argv[0]);
break;
default:
printf("Unknown option or invalid format!\n");
printf("Pls: %s --help for more info\n", argv[0]);
break;
}
}
}
int set_serial(int fd, int baud_rate, int nBits, char nEvent, int nStop)
{
struct termios tty_cfg;
memset(&tty_cfg, 0, sizeof(tty_cfg));
tty_cfg.c_cflag |= (CLOCAL|CREAD); /* CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 */
tty_cfg.c_cflag &= ~CSIZE; /* 设置数据位 */
switch(baud_rate) {
case 2400:
cfsetispeed(&tty_cfg, B2400);
cfsetospeed(&tty_cfg, B2400);
break;
case 4800:
cfsetispeed(&tty_cfg, B4800);
cfsetospeed(&tty_cfg, B4800);
break;
case 9600:
cfsetispeed(&tty_cfg, B9600);
cfsetospeed(&tty_cfg, B9600);
break;
case 115200:
cfsetispeed(&tty_cfg, B115200);
cfsetospeed(&tty_cfg, B115200);
break;
case 460800:
cfsetispeed(&tty_cfg, B460800);
cfsetospeed(&tty_cfg, B460800);
break;
default:
cfsetispeed(&tty_cfg, B9600);
cfsetospeed(&tty_cfg, B9600);
break;
}
switch(nBits) {
case 7:
tty_cfg.c_cflag |= CS7;
break;
case 8:
tty_cfg.c_cflag |= CS8;
break;
}
switch(nEvent) {
case '0': /* 奇校验 */
tty_cfg.c_cflag |= PARENB; /* 开启奇偶校验 */
tty_cfg.c_iflag |= (INPCK | ISTRIP); /*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特 */
tty_cfg.c_cflag |= PARODD; /*启用奇校验(默认为偶校验)*/
break;
case 'E': /*偶校验*/
tty_cfg.c_cflag |= PARENB; /*开启奇偶校验 */
tty_cfg.c_iflag |= ( INPCK | ISTRIP); /*打开输入奇偶校验并去除字符第八个比特*/
tty_cfg.c_cflag &= ~PARODD; /*启用偶校验*/
break;
case 'N': /*无奇偶校验*/
tty_cfg.c_cflag &= ~PARENB;
break;
}
/* 设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB */
if(nStop == 1)
tty_cfg.c_cflag &= ~CSTOPB; /*默认为一位停止位; */
else if( nStop == 2)
tty_cfg.c_cflag |= CSTOPB; /* CSTOPB表示送两位停止位 */
/* flow control option */
tty_cfg.c_cflag |= CRTSCTS;
/* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/
tty_cfg.c_cc[VTIME] = 0; /* 非规范模式读取时的超时时间;*/
tty_cfg.c_cc[VMIN] = 0; /* 非规范模式读取时的最小字符数*/
tcflush(fd, TCIFLUSH); /* tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
/*激活配置使其生效*/
if((tcsetattr(fd, TCSANOW, &tty_cfg)) != 0) {
printf("com set error");
exit(1);
}
return 0;
}
void dump_data(char *buf)
{
int i;
for(i=0; i<TEST_LEN; i++) {
if(i%16 == 0)
printf("\n");
printf("0x%x, ", buf[i]);
}
}
char buff[TEST_LEN];
int main(int argc, char *argv[])
{
int fd=0;
int cnt=0;
int sum=0;
static int num=0;
char *p=NULL;
parse_cmd(argc, argv);
printf("RX: dev_name=%s, baud_rate=%d\n", dev_name, baud_rate);
fd = open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < 0) {
printf("Can't Open %s\n", dev_name);
return -1;
}
set_serial(fd, baud_rate, 8, 'N', 1);
sleep(1);
memset(buff, 0x0, TEST_LEN);
//printf("start recv: %ds\n", time(NULL));
p = &buff[0];
while(1) {
cnt = read(fd, p, TEST_LEN);
if(cnt <= 0) {
//sleep(1);
continue;
}
sum += cnt;
if(sum >= TEST_LEN)
break;
p += cnt;
printf("RX%d: cnt = %d, sum = %d\n", num++, cnt, sum);
}
printf("recv %d: %ds\n", sum, time(NULL));
p = NULL;
close(fd);
//dump_data(buff);
return 0;
}