串口对传测试

来源:互联网 发布:苹果4s如何变成4g网络 编辑:程序博客网 时间:2024/06/16 23:43

app.c

#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <termio.h>#include <time.h>#include <sys/epoll.h>#include <pthread.h>#include <time.h>     #include<sys/time.h> //#define UART_DEV           "/dev/ttyS2"#define UART_DATABITS      8#define UART_PARITY        0#define UART_STOPBITS      1#define UART_FLOW          0#define UART_BAUD          115200#define MAX_BUF_SIZE       1024     //4096#define TTYS1_SEND_FILE   "/cache/uart_test/ttys1_send.bin"#define TTYS1_RECV_FILE   "/cache/uart_test/ttys1_recv.bin"#define TTYS2_SEND_FILE   "/cache/uart_test/ttys2_send.bin"#define TTYS2_RECV_FILE   "/cache/uart_test/ttys2_recv.bin"int epfd;struct epoll_event event; char *send_file_name = NULL;char *recv_file_name = NULL;/*** 设置串口属性 ***/int setup_port(int fd, int baud, int flow_ctrl, int databits, int parity, int stopbits);int reset_port(int fd);int write_data(int fd, void *buf, int len);void print_usage(char *program_name);void *send_file(void *arg);void recv_file(int fd);void epoll_init(int fd)   //fd为需要epoll监控的文件描述符{    int ret = -1;    epfd = epoll_create(1);    if (epfd < 0){        printf("Epoll_create fail: %s(errno: %d)\n", strerror(errno), errno);        return ;    }memset(&event, 0, sizeof(event));    event.data.fd = fd;  event.events = EPOLLIN | EPOLLET;     ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);    if (ret < 0){        printf("Epoll_ctl fail: %s(errno: %d)\n", strerror(errno), errno);        return ;    }    return ;}int main(int argc, char *argv[]){int fd;int baud;int ret = -1;int flow_ctrl;int databits;int stopbits;int parity;int read_or_write;    struct timeval startTime,endTime;      float Timeuse;  if (argc != 4) {fprintf(stderr, "Usage: %s /dev/ttySx xx(baud) xx(flow_control) \n", argv[0]);return 1;}baud = atoi(argv[2]);if ((baud < 0) || (baud > 1500000)) {        //1 波特率baud fprintf(stderr, "Invalid baudrate!\n");return 1;}    //flow_ctrl = UART_FLOW;flow_ctrl = atoi(argv[3]);    //2 流控flow_ctrl if(flow_ctrl < 0 || flow_ctrl > 2){fprintf(stderr, "Invalid flow_ctrl!\n");return 1;}databits = UART_DATABITS;//3 数据位databits  if ((databits < 5) || (databits > 8)) {fprintf(stderr, "Invalid databits!\n");return 1;}parity = UART_PARITY;    //4 鸡狗效验 parity if ((parity < 0) || (parity > 2)) {fprintf(stderr, "Invalid parity!\n");return 1;}stopbits = UART_STOPBITS;//5 停止位stopbitsif ((stopbits < 1) || (stopbits > 2)) {fprintf(stderr, "Invalid stopbits!\n");return 1;}#if 0read_or_write = atoi(argv[4]);//6 读写方向read_or_write if(read_or_write < 0 || read_or_write > 1){fprintf(stderr, "Invalid read_or_write!\n");return 1;}#endif    gettimeofday(&startTime,NULL);     printf("gettimeofday-----\n");printf("Open the recv uart%s \n",argv[1]);fd = open(argv[1], O_RDWR | O_NOCTTY | O_NONBLOCK);                 if (fd < 0) {fprintf(stderr, "open <%s> error %s\n", argv[1], strerror(errno));return 1;}printf("Open uart%s success\n",argv[1]);if (setup_port(fd, baud, flow_ctrl, databits, parity, stopbits)) {fprintf(stderr, "setup_port error %s\n", strerror(errno));close(fd);return 1;}tcflush(fd,TCIOFLUSH);epoll_init(fd);#if 1if (!strcmp(argv[1], "/dev/ttyS1")) {send_file_name = TTYS1_SEND_FILE;recv_file_name = TTYS1_RECV_FILE;} else if (!strcmp(argv[1], "/dev/ttyS2")) {send_file_name = TTYS2_SEND_FILE;recv_file_name = TTYS2_RECV_FILE;} else {fprintf(stderr, "device invalid\n");return -1;}pthread_t tid;ret = pthread_create(&tid, NULL, send_file, (void *)&fd);//线程发送测试if (ret != 0){fprintf(stderr, "Create a thread error!\n");exit(1);}printf("Begin to recv data\n");recv_file(fd);//进程文件接收测试 pthread_join(tid, NULL);#else//只做接收测试 printf("Begin to recv data\n");recv_file(fd);//printf("Begin to send data\n");//send_file((void *)&fd);#endifreset_port(fd);close(fd);    gettimeofday(&endTime,NULL);            Timeuse = 1000000*(endTime.tv_sec - startTime.tv_sec) + (endTime.tv_usec - startTime.tv_usec);           Timeuse /= 1000000;            printf("Time use = %f !!!!!\n",Timeuse);printf("Process end.\n");return 0;}void recv_file(int fd){    int nfds = 0;    int read_num = 0;    int time_out = 1000; //msint out_times = 0;    struct epoll_event ev;  int ret = -1;int count = 0;int len;int recv_fd = 0;char buf[MAX_BUF_SIZE];fprintf(stderr, "Begin to recv:\n");recv_fd = open(recv_file_name, O_RDWR | O_CREAT | O_TRUNC, 0764);if (recv_fd < 0) {fprintf(stderr, "Open recv file error: %s(errno: %d)\n", strerror(errno), errno);return ;}len = MAX_BUF_SIZE;             //  ---------------while(1) {nfds = epoll_wait(epfd, &ev, 1, time_out);              if (nfds == 0){printf("Epoll time out.\n");if ((out_times ++) == 5) {break;}} else if (nfds > 0 && (ev.events & EPOLLIN)){        //detect object uart out_times = 0;while (1) {memset(buf, 0, sizeof(buf));/***      read data from file to buf      ***/read_num = read(ev.data.fd, (char *)buf, len);if (read_num < 0){if (errno == EAGAIN) {//printf("NOthing data in uart FIFO\n");break;}printf("Read data error: %s(errno: %d)  \n", strerror(errno), errno);return ;} else if (read_num == 0) {break;} else {    //                printf("read_num: %d\n", read_num);count = 0;while (count < read_num) {ret = write(recv_fd, buf + count, read_num - count);if (ret < 0) {fprintf(stderr, "Write data to rev_file error: %s(errno: %d)\n", strerror(errno), errno);return ;}count += ret;}}}}else {printf("epoll_wait happen some error(ret: %d)!\n", nfds);return ;}}printf("Receive file end.\n");return ;}void *send_file(void *arg){int fd = *(int *)arg;intret = -1;int send_fd = 0;char buf[MAX_BUF_SIZE];//4096 4K int len = 0;    //unsigned int readcount = 0;printf("Ready send data to serial...\n");#if 1sleep(1);send_fd = open(send_file_name, O_RDWR);//打开所要发送的文件(local file) if (send_fd < 0) {fprintf(stderr, "Open send file error: %s(errno: %d)\n", strerror(errno), errno);return NULL;}#endifwhile (1)    {memset(buf, 0, sizeof(buf));len = read(send_fd , buf, sizeof(buf));if (len == 0) {            printf("read 0 byte from send_file ! \n");break;          }         else if (len < 0) {printf("read send_file error ! \n");}//        else//          printf("read %d byte from %s to buff ! \n",len,send_file_name);        /***   write send_data to buff    ***/ret = write_data(fd, buf, len);if (ret != len){            printf("write %d byte from buff to uart)\n",ret);fprintf(stderr, "Write Serial error: %s(errno: %d)!\n", strerror(errno), errno);return NULL;}//        else //           printf("write %d byte from buff to uart ! \n",len);       }printf("send data end\n");return NULL;}static int baudflag_arr[] = {B921600, B460800, B230400, B115200, B57600, B38400,B19200,  B9600,   B4800,   B2400,   B1800,  B1200,B600,    B300,    B150,    B110,    B75,    B50,B500000, B1500000};static int speed_arr[] = {921600,  460800,  230400,  115200,  57600,  38400,19200,   9600,    4800,    2400,    1800,   1200,600,     300,     150,     110,     75,     50,500000, 1500000};int speed_to_flag(int speed){int i;for (i = 0;  i < sizeof(speed_arr)/sizeof(int);  i++) {if (speed == speed_arr[i]) {return baudflag_arr[i];}}fprintf(stderr, "Unsupported baudrate, use 115200 instead!\n");return B115200;}static struct termio oterm_attr;/************************************************************************************ * 名称    :setup_port * 功能    :设置串口数据位,停止位和效验位 * 入口参数: *     @fd         串口文件描述符 *     @baud       串口波特率 *     @flow_ctrl  数据流控制 *                     0:无流控 *                     1:硬件流控 *                     2:软件流控           *      @databits   数据位   取值为 5,6,7,8 *      @stopbits   停止位   取值为 1,2 *      @parity     效验类型 取值为 0,1,2 * 出口参数:  *      正确返回为0,错误返回为-1 **************************************************************************************/int setup_port(int fd, int baud, int flow_ctrl, int databits, int parity, int stopbits){struct termios term_attr;/* Get current setting */if (ioctl(fd, TCGETA, &term_attr) < 0) {return -1;}/* Backup old setting */memcpy(&oterm_attr, &term_attr, sizeof(struct termios));term_attr.c_iflag &= ~(INLCR | IGNCR | ICRNL | ISTRIP | IXON);term_attr.c_oflag &= ~(OPOST | ONLCR | OCRNL);term_attr.c_lflag &= ~(ISIG | ECHO | ICANON | NOFLSH);term_attr.c_cflag &= ~CBAUD;term_attr.c_cflag |= CREAD | speed_to_flag(baud);    printf("current term_attr.c_cflag = 0x%x  \n",term_attr.c_cflag);    printf("CRTSCTS = 0x%x  \n",CRTSCTS);/*Set flow_ctrl*/switch(flow_ctrl){case 0:term_attr.c_cflag &= ~CRTSCTS;      //no flow control            printf("no flow_ctrl term_attr.c_cflag = 0x%x \n",term_attr.c_cflag);break;   case 1:term_attr.c_cflag |= CRTSCTS;       //flow control by hardware               printf("hard flow_ctrl term_attr.c_cflag = 0x%x \n",term_attr.c_cflag);   break;case 2:term_attr.c_cflag |= IXON | IXOFF | IXANY;  //flow control by software             printf("soft flow_ctrl \n"); break;}term_attr.c_cflag &= ~(CSIZE);/* Set databits */switch (databits) {case 5:term_attr.c_cflag |= CS5;break;case 6:term_attr.c_cflag |= CS6;break;case 7:term_attr.c_cflag |= CS7;break;case 8:default:term_attr.c_cflag |= CS8;break;}/* Set parity */switch (parity) {case 1:   /* Odd parity */term_attr.c_cflag |= (PARENB | PARODD);break;case 2:   /* Even parity */term_attr.c_cflag |= PARENB;term_attr.c_cflag &= ~(PARODD);break;case 0:   /* None parity */default:term_attr.c_cflag &= ~(PARENB);break;}/* Set stopbits */switch (stopbits) {case 2:   /* 2 stopbits */term_attr.c_cflag |= CSTOPB;break;case 1:   /* 1 stopbits */default:term_attr.c_cflag &= ~CSTOPB;break;}    printf("setup term_attr.c_cflag = 0x%x \n",term_attr.c_cflag);term_attr.c_cc[VMIN] = 1;term_attr.c_cc[VTIME] = 0;tcflush(fd,TCIFLUSH);if((tcsetattr(fd,TCSANOW,&term_attr))!=0){printf("fcntl is error\n");}/*if (ioctl(fd, TCSETAW, &term_attr) < 0) {return -1;}if (ioctl(fd, TCFLSH, 2) < 0) {return -1;}*/return 0;}int reset_port(int fd){if (ioctl(fd, TCSETAW, &oterm_attr) < 0) {return -1;}return 0;}int write_data(int fd, void *buf, int len){int count;int ret;ret = 0;count = 0;while (count < len) {//open fd noblock            ret = write(fd, (char*)buf + count, len - count);    if (ret < 0)             {if (errno == EAGAIN) {continue;}    fprintf(stderr, "Write error %s\n", strerror(errno));    break;    }      count += ret;}return count;}void print_usage(char *program_name){fprintf(stderr,"*************************************\n""  A Simple Serial Port Test Utility\n""*************************************\n\n""Usage:\n %s <device> <baud> <flow_ctrl> <read_or_write>\n""       flow_ctrl:0(None), 1(hard), 2(soft)""       read_or_write: 0(read), 1(write)\n""Example:\n  %s /dev/ttyS2 115200 0 0\n\n",program_name, program_name   );return ;}







阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 拉拖维亚 赛尔维亚 西尔维亚 斯维亚 拉托维亚 吉诺维亚 维亚 布拉格斯拉维亚 克萨维亚之水 塞尔维亚人是否欢迎中国人 塞尔维亚旅游 塞尔维亚帝国 塞尔维亚女排名单 玻利维亚天空之镜 玻利维亚泥石流 洛丝维亚瑟在线播放 塞尔维亚男篮 塞尔维亚人女人很漂亮 奥利维亚库克 日本女排胜塞尔维亚 女排世界杯中国对塞尔维亚 维仕担保是哪个网贷 维他柠檬茶为什么上瘾 维他柠檬茶上瘾 维他柠檬茶为什么会上瘾 维他 盐酸屈他维林片 屈他维林 赵维山中国为什么不抓他 五维他口服液主要功效 五维他口服液 维他柠檬茶多少钱一瓶 医维他 康维他麦卢卡蜂蜜 香港维他柠檬茶 维他豆奶 维他柠檬茶表情包 维他芒果汁 麦维他 维他奶 崩坏位面见闻录 维他乌龙茶