Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72876
  • 博文数量: 11
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 94
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-11 15:27
个人简介

给自己一个城堡

文章分类
文章存档

2017年(3)

2016年(8)

我的朋友

分类: 嵌入式

2017-01-24 08:21:39


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <termios.h>
  10. #include <errno.h>
  11. #include <limits.h>
  12. #include <asm/ioctls.h>
  13. #include <time.h>
  14. #include <pthread.h>
  15. #include <sys/ipc.h>
  16. #include <sys/msg.h>

  17. #include "lib-slip.h"

  18. #include "util-port.h"


  19. #define MSG printf

  20. static int gPortFd;
  21. static int gMsgId;
  22. static int gNumPort;
  23. MutilSlipAttr_t gUartSlip = {0};

  24. UartInfoAttr_t gUartInfo[] = {
  25.     [0] = {
  26.         .mPath = UART1_PATH,
  27.         .mMode = UART_115200_8N1,
  28.     },
  29.     [1] = {
  30.         .mPath = UART2_PATH,
  31.         .mMode = UART_115200_8N1,
  32.     },
  33.     [2] = {
  34.         .mPath = UART3_PATH,
  35.         .mMode = UART_115200_8N1,
  36.     },
  37.     [3] = {
  38.         .mPath = UART4_PATH,
  39.         .mMode = UART_115200_8N1,
  40.     },
  41. };

  42. int open_serial(int port){
  43.     int fd;
  44.     struct termios opt;

  45.     if(!gUartInfo[port].mPath){
  46.         return -1;
  47.     }
  48.     fd = open(gUartInfo[port].mPath, O_RDWR | O_NOCTTY);
  49.     if(fd < 0){
  50.         MSG("open uart fail.\n");
  51.         return -1;
  52.     }

  53.     tcgetattr(fd, &opt);

  54.     switch(gUartInfo[port].mMode){
  55.         case     UART_9600_8N1:{
  56.             cfsetispeed(&opt, B9600);
  57.              cfsetospeed(&opt, B9600);

  58.              opt.c_cflag &= ~PARENB;
  59.             opt.c_cflag &= ~CSTOPB;
  60.             opt.c_cflag &= ~CSIZE;
  61.             opt.c_cflag |= CS8;
  62.             break;
  63.         }
  64.         case     UART_9600_8O1:{
  65.             cfsetispeed(&opt, B9600);
  66.              cfsetospeed(&opt, B9600);

  67.              opt.c_cflag |= PARENB;
  68.             opt.c_cflag |= ~PARODD;
  69.             opt.c_cflag &= ~CSTOPB;
  70.             opt.c_cflag &= ~CSIZE;
  71.             opt.c_cflag |= CS8;
  72.             break;
  73.         }
  74.         case     UART_9600_8E1:{
  75.             cfsetispeed(&opt, B9600);
  76.              cfsetospeed(&opt, B9600);

  77.              opt.c_cflag |= PARENB;
  78.             opt.c_cflag &= ~PARODD;
  79.             opt.c_cflag &= ~CSTOPB;
  80.             opt.c_cflag &= ~CSIZE;
  81.             opt.c_cflag |= CS8;
  82.             break;
  83.         }

  84.         case    UART_115200_8N1:{
  85.             cfsetispeed(&opt, B115200);
  86.              cfsetospeed(&opt, B115200);

  87.              opt.c_cflag &= ~PARENB;
  88.             opt.c_cflag &= ~CSTOPB;
  89.             opt.c_cflag &= ~CSIZE;
  90.             opt.c_cflag |= CS8;

  91.             break;
  92.         }
  93.         case    UART_115200_8O1:{
  94.             cfsetispeed(&opt, B115200);
  95.              cfsetospeed(&opt, B115200);

  96.              opt.c_cflag |= PARENB;
  97.             opt.c_cflag |= ~PARODD;
  98.             opt.c_cflag &= ~CSTOPB;
  99.             opt.c_cflag &= ~CSIZE;
  100.             opt.c_cflag |= CS8;
  101.             break;
  102.         }
  103.         case    UART_115200_8E1:{
  104.             cfsetispeed(&opt, B115200);
  105.              cfsetospeed(&opt, B115200);

  106.              opt.c_cflag |= PARENB;
  107.             opt.c_cflag &= ~PARODD;
  108.             opt.c_cflag &= ~CSTOPB;
  109.             opt.c_cflag &= ~CSIZE;
  110.             opt.c_cflag |= CS8;
  111.             break;
  112.         }

  113.         default:{
  114.             return -1;
  115.             //break;
  116.         }
  117.     }

  118.     opt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  119.     opt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  120.     opt.c_oflag &= ~(OPOST);

  121.     opt.c_cc[VMIN] = 200;
  122.     opt.c_cc[VTIME] = 1;

  123.     if(tcsetattr(fd, TCSANOW, &opt) < 0){
  124.         printf("set attr error.\n");
  125.         return -1;
  126.     }

  127.     tcflush(fd, TCIOFLUSH);

  128.     return fd;
  129. }

  130. int stream_parse( uint8_t *p, int len ){
  131.     UartMsgInfo_t msg;
  132.     int ret;
  133.     while(len--){
  134.         ret = recv_packet(&gUartSlip, *p++);
  135.         if(ret == 1){
  136.             if(gUartSlip.mBuffIdx){
  137.                 //q
  138.                 msg.mType = PORT_MSG_TYPE_RCV; //must not be zero
  139.                 msg.mPayLoad.mLen = gUartSlip.mBuffIdx;
  140.                 memcpy(msg.mPayLoad.mData, gUartSlip.mBuff, gUartSlip.mBuffIdx);
  141.                 if((msgsnd(gMsgId, (void *)&msg, sizeof(UartMsgPayLoad_t), IPC_NOWAIT)) < 0){
  142.                     printf("port%d rcv msg send error.\n", gNumPort+1);
  143.                 }
  144.                 else{
  145.                     printf("port%d post rcv msg ok.\n", gNumPort+1);
  146.                 }
  147.             }
  148.         }
  149.     }
  150.     return 0;
  151. }

  152. void *port_read_thread(void *arg){
  153.     int len;
  154.     int iRet;
  155.     fd_set readSet;
  156.     uint8_t rcvBuff[UART_EACH_BUFF_RCV_MAX];


  157.     while(1){
  158.         FD_ZERO(&readSet);
  159.         FD_SET (gPortFd, &readSet);
  160.         
  161.         iRet = select(gPortFd + 1, &readSet, NULL, NULL, NULL);
  162.         if(iRet == -1){
  163.             MSG("select error.\n");
  164.             exit(-1);
  165.         }
  166.         else if(iRet == 0){
  167.             MSG("No data, exit.\n");
  168.             break;
  169.         }
  170.         else{
  171.             //
  172.             if(FD_ISSET(gPortFd, &readSet)){
  173.                 MSG("Port %d Rcv Data.\n", gNumPort+1);
  174.                 len = read(gPortFd, rcvBuff, UART_EACH_BUFF_RCV_MAX);
  175.                 #if 0 //test
  176.                 for(j = 0; j < len; j++)
  177.                     MSG(" %02x", rcvBuff[j]);
  178.                 MSG("\n");
  179.                 #endif
  180.                 if(len > 0){
  181.                     stream_parse( rcvBuff, len );
  182.                 }
  183.             }
  184.         }
  185.     }
  186.     pthread_exit(NULL);    
  187. }


  188. void *port_write_thread(void *arg){
  189.     UartMsgInfo_t msg;
  190.     int i;
  191.     int ret;
  192.     while(1){
  193.         if((ret = msgrcv(gMsgId, (void *)&msg, sizeof(UartMsgPayLoad_t), PORT_MSG_TYPE_SND, 0)) == -1){
  194.             printf("port%d get snd msg error.\n", gNumPort+1);
  195.         }
  196.         else{
  197.             printf("sMsg: type = %d, payloadLen = %d.\n", msg.mType, msg.mPayLoad.mLen);
  198.             printf(" data=");
  199.             for(i = 0; i < msg.mPayLoad.mLen; i++)
  200.                 printf(" %02x", msg.mPayLoad.mData[i]);
  201.             printf("\n");

  202.             if((ret = write(gPortFd, msg.mPayLoad.mData, msg.mPayLoad.mLen)) < 0){
  203.                 MSG("port%d send error.\n", gNumPort+1);
  204.             }
  205.             else{
  206.                 MSG("port%d send ok.\n", gNumPort+1);
  207.             }
  208.         }
  209.     }

  210. }


  211. int main(int argc, char const *argv[])
  212. {
  213.     /* code */
  214.     int key;
  215.     int ret;
  216.     pthread_t stid,rtid;


  217.     if(argc != 2){
  218.         MSG("argc error.\n");
  219.         return -1;
  220.     }

  221.     gNumPort = atoi(argv[1]);
  222.     if( (gNumPort > UART_NUM_MAX) || (gNumPort == 0)){
  223.         MSG("serial port not existed.\n");
  224.         return -1;
  225.     }
  226.     gNumPort -= 1;

  227.     if((key = ftok(gUartInfo[gNumPort].mPath, UART_MSG_KEY)) == -1){
  228.         MSG("port%d msg key error.\n", gNumPort+1);
  229.         return -1;
  230.     }

  231.     if((gMsgId = msgget(key, IPC_CREAT|0600)) == -1){
  232.         MSG("prot%d msg error.\n", gNumPort+1);
  233.         return -1;
  234.     }
  235.     printf("port%d msg ok. qid = %d\n", gNumPort+1, gMsgId);



  236.     
  237.     if((gPortFd = open_serial(gNumPort)) <= 0){
  238.         MSG("open serial port%d error.\n", gNumPort+1);
  239.         return -1;
  240.     }
  241.     MSG("open serial %d ok.[fd=%d].\n",gNumPort+1, gPortFd);

  242.     ret = pthread_create(&rtid, NULL, port_read_thread, NULL);
  243.     if(ret != 0){
  244.         MSG("port%d create port_read_thread error.\n", gNumPort+1);
  245.         return -1;
  246.     }

  247.     ret = pthread_create(&stid, NULL, port_write_thread, NULL);
  248.     if(ret != 0){
  249.         MSG("port%d create port_write_thread error.\n", gNumPort+1);
  250.         return -1;
  251.     }


  252.     pthread_join(rtid, NULL);
  253.     pthread_join(stid, NULL);

  254.     if(msgctl(gMsgId, IPC_RMID, NULL) < 0){
  255.         MSG("port%d msg ctl error.\n", gNumPort+1);
  256.     }

  257.     return 0;
  258. }
基于多线程实现串口自由收发
阅读(1978) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~