linux 调试串口测试程序(pc与开发板通信)
验证调试串口的功能,数据流向:pc->board->pc
代码:uart_sr.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <string.h> #include <getopt.h> #include <pthread.h> #define SIZE (5 * 1024 *1024) #define SIZE_1K ( 1024) #define SIZE_10K (10 *1024) #define SIZE_20K (20 *1024) #define SIZE_50K (50 *1024) #define SIZE_100K (100 *1024) #define SIZE_1M (1024 *1024) #define SIZE_2M (2 * 1024 *1024) #define SIZE_3M (3 * 1024 *1024) #define SIZE_4M (4 * 1024 *1024) #define SIZE_5M (5 * 1024 *1024) int g_fd; int g_size; static const char short_options[] = "s:d:b:h"; static const struct option long_options[] = { {"size", required_argument, NULL, 's'}, {"device", required_argument, NULL, 'd'}, {"baudrate", required_argument, NULL, 'p'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0}}; static void set_baudrate(int fd, int nSpeed) { struct termios newtio; tcgetattr(fd, &newtio); switch (nSpeed) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 19200: cfsetispeed(&newtio, B19200); cfsetospeed(&newtio, B19200); break; case 38400: cfsetispeed(&newtio, B38400); cfsetospeed(&newtio, B38400); break; case 57600: cfsetispeed(&newtio, B57600); cfsetospeed(&newtio, B57600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 230400: cfsetispeed(&newtio, B230400); cfsetospeed(&newtio, B230400); break; default: printf("\tSorry, Unsupported baud rate, use previous baudrate!\n\n"); break; } tcsetattr(fd,TCSANOW,&newtio); } static void set_termios(int fd) { struct termios term; tcgetattr(fd, &term); tcgetattr(fd, &term); term.c_cflag &= ~(CSIZE | CSTOPB | PARENB | INPCK); term.c_cflag |= (CS8 | CLOCAL | CREAD); term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); term.c_oflag &= ~(OPOST | ONLCR | OCRNL); term.c_iflag &= ~(ICRNL |INLCR | IXON | IXOFF | IXANY); term.c_cc[VTIME] = 0; term.c_cc[VMIN] = 1; tcgetattr(fd, &term); } void *thread_send(void) { int i = 0; int len = 0; unsigned char buff[SIZE]; struct termios term; printf("send start\n"); tcgetattr(g_fd, &term); tcflush(g_fd, TCOFLUSH); tcsetattr(g_fd, TCSAFLUSH, &term); for (i = 0; i < SIZE; i++) buff[i] = i % 256; len = write(g_fd, buff, g_size); printf("send size:%d\n", len); } void *thread_rece(void) { unsigned char buff[SIZE] = {0}; struct termios term; int select_ret = 0; int len = 0; int total = 0; int flag = 0; int i = 0; fd_set fds; struct timeval timeout; printf("rece start\n"); tcgetattr(g_fd, &term); tcflush(g_fd, TCIOFLUSH); tcsetattr(g_fd, TCSAFLUSH, &term); while (1) { if ((flag == 1)||(flag == 2)) break; timeout.tv_sec = 10; timeout.tv_usec = 0; FD_ZERO(&fds); FD_SET(g_fd, &fds); select_ret = select(g_fd + 1, &fds, NULL, NULL, &timeout); switch (select_ret) { case -1: exit(-1); case 0: { flag = 2; //timeout break; } default: if (FD_ISSET(g_fd,&fds)) { len = read(g_fd, &buff[total] , 256); total += len; } printf("receiving:%d\n", total); if(total == g_size) { flag = 1; //total num is correct break; } } } if (flag == 1) { for(i = 0; i < g_size; i++) { if(buff[i] != i % 256) { flag = 3; //total num is correct, data error break; } } } if (flag == 1) printf("UART TEST SUCCESS\n"); else printf("UART TEST FAIL\n"); } static int parse_size(char *p) { if (p == NULL) return -1; if (!strcmp(p, "1K")) g_size = SIZE_1K; else if (!strcmp(p, "10K")) g_size = SIZE_10K; else if (!strcmp(p, "20K")) g_size = SIZE_20K; else if (!strcmp(p, "50K")) g_size = SIZE_50K; else if (!strcmp(p, "100K")) g_size = SIZE_100K; else if (!strcmp(p, "1M")) g_size = SIZE_1M; else if (!strcmp(p, "2M")) g_size = SIZE_2M; else if (!strcmp(p, "3M")) g_size = SIZE_3M; else if (!strcmp(p, "4M")) g_size = SIZE_4M; else if (!strcmp(p, "5M")) g_size = SIZE_5M; else { printf("please input correct size\n"); return -1; } return 0; } int main(int argc, char *argv[]) { char *pSize = NULL; char *pDevice = NULL; int baudrate = 115200; int ret = 0; int cmd_parser_ret = 0; pthread_t send_id, rece_id; if (argc != 7) { printf("please run ./sr -h for help\n"); return -1; } while ((cmd_parser_ret = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (cmd_parser_ret) { case 's': pSize = optarg; break; case 'd': pDevice = optarg; break; case 'b': baudrate = atoi(optarg); break; case 'h': printf("UART TEST HELP INFORMATION\n"); printf(">>> -d/--device [DEVIDE NAME,/dev/ttyS0]\n"); printf(">>> -s/--size [TEST SIZE,1K/10K/50K/100K/1M/2M/5M]\n"); printf(">>> -b/--baudrate [SAMPLE BAUDRATE,9600,115200]\n"); return 0; } } parse_size(pSize); g_fd = open(pDevice, O_RDWR | O_NOCTTY); if (0 > g_fd) { printf("open fail\n"); return -1; } set_baudrate(g_fd, baudrate); set_termios(g_fd); ret = pthread_create(&send_id, NULL, (void *)thread_send, NULL); if (ret < 0) { printf("thread error\n"); return -1; } ret = 0; ret = pthread_create(&rece_id, NULL, (void *)thread_rece, NULL); if (ret < 0) { printf("thread error\n"); return -1; } pthread_join(send_id, NULL); pthread_join(rece_id, NULL); close(g_fd); return 0; }
uart_repeate.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <string.h> #include <getopt.h> #define SIZE (5 * 1024 * 1024) static const char short_options[] = "d:b:h"; static const struct option long_options[] = { {"device", required_argument, NULL, 'd'}, {"baudrate", required_argument, NULL, 'b'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0}}; static void set_baudrate(int fd, int nSpeed) { struct termios newtio; tcgetattr(fd, &newtio); switch (nSpeed) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 19200: cfsetispeed(&newtio, B19200); cfsetospeed(&newtio, B19200); break; case 38400: cfsetispeed(&newtio, B38400); cfsetospeed(&newtio, B38400); break; case 57600: cfsetispeed(&newtio, B57600); cfsetospeed(&newtio, B57600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 230400: cfsetispeed(&newtio, B230400); cfsetospeed(&newtio, B230400); break; default: printf("\tSorry, Unsupported baud rate, use previous baudrate!\n\n"); break; } tcsetattr(fd,TCSANOW,&newtio); } static void set_termios(int fd) { struct termios term; tcgetattr(fd, &term); tcgetattr(fd, &term); term.c_cflag &= ~(CSIZE | CSTOPB | PARENB | INPCK); term.c_cflag |= (CS8 | CLOCAL | CREAD); term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); term.c_oflag &= ~(OPOST | ONLCR | OCRNL); term.c_iflag &= ~(ICRNL |INLCR | IXON | IXOFF | IXANY); term.c_cc[VTIME] = 0; term.c_cc[VMIN] = 1; tcflush(fd, TCIOFLUSH); tcsetattr(fd, TCSAFLUSH, &term); tcgetattr(fd, &term); } int main(int argc, char *argv[]) { int cmd_parser_ret = 0; char *pDevice = NULL; int baudrate = 115200; struct termios term; int fd; fd_set fds; struct timeval timeout; unsigned char buff[SIZE] = {0}; int total = 0; int select_ret = 0; int len = 0; if(argc != 5) { printf("please run ./sr -h for help\n"); return -1; } while ((cmd_parser_ret = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (cmd_parser_ret) { case 'd': pDevice = optarg; break; case 'b': baudrate = atoi(optarg); break; case 'h': printf("UART TEST HELP INFORMATION\n"); printf(">>> -d/--device [DEVICE NAME,/dev/ttyS0]\n"); printf(">>> -b/--baudrate [UART BAUDRATE,9600,115200]\n"); return 0; } } fd = open(pDevice, O_RDWR | O_NOCTTY); if (0 > fd) { printf("open fail\n"); return -1; } set_baudrate(fd, baudrate); set_termios(fd); printf("repeate start\n"); while (1) { timeout.tv_sec = 10; timeout.tv_usec = 0; FD_ZERO(&fds); FD_SET(fd, &fds); select_ret = select(fd + 1, &fds, NULL, NULL, &timeout); switch (select_ret) { case -1: exit(-1); case 0: { printf("exit,timeout 10s\n"); exit(-1); } default: if (FD_ISSET(fd,&fds)) { len = read(fd, buff , 256); write(fd, buff, len); total += len; printf("repeate:%d\n", total); } } } close(fd); return 0; }
readme
串口测试方法: uart_sr.c 发送数据,接收数据函数,运行在pc机上 编译命令:gcc uart_sr.c -o uart_sr -pthread 运行命令:./uart_sr -s 1M -b 115200 -d /dev/ttyUSB1 uart_repeate.c 接收收据,发送数据,起转发的作用,运行在板子上 编译命令:aarch64-linux-gnu-gcc uart_repeate.c -o uart_repeate 运行命令:./uart_repeate -b 115200 -d /dev/ttyS0 注意:测试前需要注释/etc/inittab文件的start_getty内容;先运行板上的uart_repeate程序,这是一个转发功能程序,超时时间为10s,10s收不到数据,程序会自动退出.