免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2990 | 回复: 0
打印 上一主题 下一主题

Linux串口测试程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-18 14:45 |只看该作者 |倒序浏览
本帖最后由 seaquester 于 2010-04-20 09:00 编辑

Linux串口测试程序
冷胜魁(Seaquester)
lengshengkui@gmail.com
2009-11-18

这是以前在做一个基于ARM的项目的时候,写的一个简单串口测试程序,同样也适用于X86平台。程序很简单,运行是通过参数指定程序是发送端还是接收端。接收端运行之后就简单的读取串口数据,打印到stdout。发送端则接受键盘输入,通过串口发送出去。如果直接回车则表示发送完毕,通知接收端退出。


  1. /******************************************************************************
  2. *
  3. * FILENAME:
  4. *     testcom.c
  5. *
  6. * DESCRIPTION:
  7. *     A utility to read/write serial port
  8. *     Usage: testcom <device> <baud> <databits> <parity> <stopbits> <read_or_write>
  9. *        databits: 5, 6, 7, 8
  10. *        parity: 0(None), 1(Odd), 2(Even)
  11. *        stopbits: 1, 2
  12. *        read_or_write: 0(read), 1(write)
  13. *     Example: testcom /dev/ttyS0 9600 8 0 1 0
  14. *
  15. * REVISION(MM/DD/YYYY):
  16. *     03/12/2008  Shengkui Leng (shengkui.leng@advantech.com.cn)
  17. *     - Initial version
  18. *
  19. ******************************************************************************/
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <errno.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <string.h>
  26. #include <termio.h>
  27. #include <time.h>


  28. #define MAX_BUF_SIZE     2048
  29. char buf[MAX_BUF_SIZE+2];

  30. #define MY_END_CHAR      0x13


  31. int setup_port(int fd, int baud, int databits, int parity, int stopbits);
  32. int reset_port(int fd);
  33. int read_data(int fd, void *buf, int len);
  34. int write_data(int fd, void *buf, int len);
  35. void print_usage(char *program_name);


  36. int main(int argc, char *argv[])
  37. {
  38.     int fd;
  39.     int baud;
  40.     int len;
  41.     int count;
  42.     int i;
  43.     int databits;
  44.     int stopbits;
  45.     int parity;
  46.     int read_or_write;


  47.     if (argc != 7) {
  48.         print_usage(argv[0]);
  49.         return 1;
  50.     }

  51.     baud = atoi(argv[2]);
  52.     if ((baud < 0) || (baud > 921600)) {
  53.         fprintf(stderr, "Invalid baudrate!\n");
  54.         return 1;
  55.     }

  56.     databits = atoi(argv[3]);
  57.     if ((databits < 5) || (databits > 8)) {
  58.         fprintf(stderr, "Invalid databits!\n");
  59.         return 1;
  60.     }

  61.     parity = atoi(argv[4]);
  62.     if ((parity < 0) || (parity > 2)) {
  63.         fprintf(stderr, "Invalid parity!\n");
  64.         return 1;
  65.     }

  66.     stopbits = atoi(argv[5]);
  67.     if ((stopbits < 1) || (stopbits > 2)) {
  68.         fprintf(stderr, "Invalid stopbits!\n");
  69.         return 1;
  70.     }

  71.     read_or_write = atoi(argv[6]);

  72.     fd = open(argv[1], O_RDWR, 0);
  73.     if (fd < 0) {
  74.         fprintf(stderr, "open <%s> error %s\n", argv[1], strerror(errno));
  75.         return 1;
  76.     }

  77.     if (setup_port(fd, baud, databits, parity, stopbits)) {
  78.         fprintf(stderr, "setup_port error %s\n", strerror(errno));
  79.         close(fd);
  80.         return 1;
  81.     }

  82.     count = 0;

  83.     if (read_or_write) {
  84.         fprintf(stderr, "Begin to send:\n");

  85.         while ( (len = read(0, buf, MAX_BUF_SIZE)) > 0 ) {
  86.             if (len == 1) {
  87.                 buf[0] = MY_END_CHAR;
  88.                 buf[1] = 0;
  89.                 write_data(fd, buf, len);
  90.                 break;
  91.             }

  92.             /* send a pack */
  93.             i = write_data(fd, buf, len);
  94.             if (i == 0) {
  95.                 fprintf(stderr, "Send data error!\n");
  96.                 break;
  97.             }

  98.             //count += len;
  99.             //fprintf(stderr, "Send %d bytes\n", len);
  100.         }

  101.     } else {

  102.         fprintf(stderr, "Begin to recv:\n");

  103.         len = MAX_BUF_SIZE;

  104.         while (1) {
  105.             /* read a pack */
  106.             i = read_data(fd, buf, len);
  107.             if (i > 0) {
  108.                 //count += i;
  109.                 //fprintf(stderr, "Recv %d byte\n", i);
  110.                 printf("%s", buf);
  111.                 if (buf[i-1] == MY_END_CHAR) {
  112.                     break;
  113.                 }
  114.             }
  115.         }
  116.     }

  117.     reset_port(fd);
  118.     close(fd);

  119.     return 0;
  120. }


  121. static int baudflag_arr[] = {
  122.     B921600, B460800, B230400, B115200, B57600, B38400,
  123.     B19200,  B9600,   B4800,   B2400,   B1800,  B1200,
  124.     B600,    B300,    B150,    B110,    B75,    B50
  125. };
  126. static int speed_arr[] = {
  127.     921600,  460800,  230400,  115200,  57600,  38400,
  128.     19200,   9600,    4800,    2400,    1800,   1200,
  129.     600,     300,     150,     110,     75,     50
  130. };


  131. /******************************************************************************
  132. * NAME:
  133. *      speed_to_flag
  134. *
  135. * DESCRIPTION:
  136. *      Translate baudrate into flag
  137. *
  138. * PARAMETERS:
  139. *      speed - The baudrate to convert
  140. *
  141. * RETURN:
  142. *      The flag
  143. ******************************************************************************/
  144. int speed_to_flag(int speed)
  145. {
  146.     int i;

  147.     for (i = 0;  i < sizeof(speed_arr)/sizeof(int);  i++) {
  148.         if (speed == speed_arr[i]) {
  149.             return baudflag_arr[i];
  150.         }
  151.     }

  152.     fprintf(stderr, "Unsupported baudrate, use 9600 instead!\n");
  153.     return B9600;
  154. }


  155. static struct termio oterm_attr;

  156. /******************************************************************************
  157. * NAME:
  158. *      stup_port
  159. *
  160. * DESCRIPTION:
  161. *      Set serial port (include baudrate, line control)
  162. *
  163. * PARAMETERS:
  164. *      fd       - The fd of serial port to setup
  165. *      baud     - Baudrate: 9600, ...
  166. *      databits - Databits: 5, 6, 7, 8
  167. *      parity   - Parity: 0(None), 1(Odd), 2(Even)
  168. *      stopbits - Stopbits: 1, 2
  169. *
  170. * RETURN:
  171. *      0 for OK; Others for ERROR
  172. ******************************************************************************/
  173. int setup_port(int fd, int baud, int databits, int parity, int stopbits)
  174. {
  175.     struct termio term_attr;

  176.     /* Get current setting */
  177.     if (ioctl(fd, TCGETA, &term_attr) < 0) {
  178.         return -1;
  179.     }

  180.     /* Backup old setting */
  181.     memcpy(&oterm_attr, &term_attr, sizeof(struct termio));

  182.     term_attr.c_iflag &= ~(INLCR | IGNCR | ICRNL | ISTRIP);
  183.     term_attr.c_oflag &= ~(OPOST | ONLCR | OCRNL);
  184.     term_attr.c_lflag &= ~(ISIG | ECHO | ICANON | NOFLSH);
  185.     term_attr.c_cflag &= ~CBAUD;
  186.     term_attr.c_cflag |= CREAD | speed_to_flag(baud);

  187.     /* Set databits */
  188.     term_attr.c_cflag &= ~(CSIZE);
  189.     switch (databits) {
  190.         case 5:
  191.             term_attr.c_cflag |= CS5;
  192.             break;

  193.         case 6:
  194.             term_attr.c_cflag |= CS6;
  195.             break;

  196.         case 7:
  197.             term_attr.c_cflag |= CS7;
  198.             break;

  199.         case 8:
  200.         default:
  201.             term_attr.c_cflag |= CS8;
  202.             break;
  203.     }

  204.     /* Set parity */
  205.     switch (parity) {
  206.         case 1:   /* Odd parity */
  207.             term_attr.c_cflag |= (PARENB | PARODD);
  208.             break;

  209.         case 2:   /* Even parity */
  210.             term_attr.c_cflag |= PARENB;
  211.             term_attr.c_cflag &= ~(PARODD);
  212.             break;

  213.         case 0:   /* None parity */
  214.         default:
  215.             term_attr.c_cflag &= ~(PARENB);
  216.             break;
  217.     }


  218.     /* Set stopbits */
  219.     switch (stopbits) {
  220.         case 2:   /* 2 stopbits */
  221.             term_attr.c_cflag |= CSTOPB;
  222.             break;

  223.         case 1:   /* 1 stopbits */
  224.         default:
  225.             term_attr.c_cflag &= ~CSTOPB;
  226.             break;
  227.     }

  228.     term_attr.c_cc[VMIN] = 1;
  229.     term_attr.c_cc[VTIME] = 0;

  230.     if (ioctl(fd, TCSETAW, &term_attr) < 0) {
  231.         return -1;
  232.     }

  233.     if (ioctl(fd, TCFLSH, 2) < 0) {
  234.         return -1;
  235.     }

  236.     return 0;
  237. }


  238. /******************************************************************************
  239. * NAME:
  240. *      read_data
  241. *
  242. * DESCRIPTION:
  243. *      Read data from serial port
  244. *
  245. *
  246. * PARAMETERS:
  247. *      fd   - The fd of serial port to read
  248. *      buf  - The buffer to keep readed data
  249. *      len  - The max count to read
  250. *
  251. * RETURN:
  252. *      Count of readed data
  253. ******************************************************************************/
  254. int read_data(int fd, void *buf, int len)
  255. {
  256.     int count;
  257.     int ret;

  258.     ret = 0;
  259.     count = 0;

  260.     //while (len > 0) {

  261.     ret = read(fd, (char*)buf + count, len);
  262.     if (ret < 1) {
  263.         fprintf(stderr, "Read error %s\n", strerror(errno));
  264.         //break;
  265.     }

  266.     count += ret;
  267.     len = len - ret;

  268.     //}

  269.     *((char*)buf + count) = 0;
  270.     return count;
  271. }


  272. /******************************************************************************
  273. * NAME:
  274. *      write_data
  275. *
  276. * DESCRIPTION:
  277. *      Write data to serial port
  278. *
  279. *
  280. * PARAMETERS:
  281. *      fd   - The fd of serial port to write
  282. *      buf  - The buffer to keep data
  283. *      len  - The count of data
  284. *
  285. * RETURN:
  286. *      Count of data wrote
  287. ******************************************************************************/
  288. int write_data(int fd, void *buf, int len)
  289. {
  290.     int count;
  291.     int ret;

  292.     ret = 0;
  293.     count = 0;

  294.     while (len > 0) {

  295.         ret = write(fd, (char*)buf + count, len);
  296.         if (ret < 1) {
  297.             fprintf(stderr, "Write error %s\n", strerror(errno));
  298.             break;
  299.         }

  300.         count += ret;
  301.         len = len - ret;
  302.     }

  303.     return count;
  304. }


  305. /******************************************************************************
  306. * NAME:
  307. *      print_usage
  308. *
  309. * DESCRIPTION:
  310. *      print usage info
  311. *
  312. * PARAMETERS:
  313. *      program_name - The name of the program
  314. *
  315. * RETURN:
  316. *      None
  317. ******************************************************************************/
  318. void print_usage(char *program_name)
  319. {
  320.     fprintf(stderr,
  321.             "*************************************\n"
  322.             "  A Simple Serial Port Test Utility\n"
  323.             "*************************************\n\n"
  324.             "Usage:\n  %s <device> <baud> <databits> <parity> <stopbits> <read_or_write>\n"
  325.             "       databits: 5, 6, 7, 8\n"
  326.             "       parity: 0(None), 1(Odd), 2(Even)\n"
  327.             "       stopbits: 1, 2\n"
  328.             "       read_or_write: 0(read), 1(write)\n"
  329.             "Example:\n  %s /dev/ttyS0 9600 8 0 1 0\n\n",
  330.             program_name, program_name
  331.            );
  332. }


  333. /******************************************************************************
  334. * NAME:
  335. *      reset_port
  336. *
  337. * DESCRIPTION:
  338. *      Restore original setting of serial port
  339. *
  340. * PARAMETERS:
  341. *      fd - The fd of the serial port
  342. *
  343. * RETURN:
  344. *      0 for OK; Others for ERROR
  345. ******************************************************************************/
  346. int reset_port(int fd)
  347. {
  348.     if (ioctl(fd, TCSETAW, &oterm_attr) < 0) {
  349.         return -1;
  350.     }

  351.     return 0;
  352. }
复制代码

               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73823/showart_2097571.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP