Chinaunix首页 | 论坛 | 博客
  • 博客访问: 93125
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-11 09:25
个人简介

浮萍漂泊本无根,天涯游子君莫问。

文章分类
文章存档

2015年(80)

我的朋友

分类: LINUX

2015-06-21 09:03:54

操作系统:ubuntu10.04

前言:
    在稍微大点的项目中,且是并发的,基本上都要使用线程来接收数据。

一,源码
    (1) 头文件

点击(此处)折叠或打开

  1. /*
  2.  * upper,上位机
  3.  * {
  4.  */

  5. /* 串口的初始化 */
  6. extern     int32_t        com_init_upper(void *param);

  7. /* 串口的发送 */
  8. extern    int32_t        com_send_upper(uint8_t *send_buffer,int32_t buffer_len);

  9. /* 串口参数设置
  10.  * 波特率,停止位,校验位,流控制,异步同步等
  11.  */
  12. extern    int32_t        com_set_upper(void *param);

  13. /* 串口设置参数生效 */
  14. extern    int32_t        com_set_effect_upper(void *param);

  15. /* 串口关闭*/
  16. extern    int32_t        com_close_upper(void *param);

  17. /* 串口接收线程关闭 */
  18. extern    int32_t        com_recv_thread_close(void *param);
  19. /*
  20.  * upper,上位机
  21.  * }
  22.  */
    
    (2) *.c 文件

点击(此处)折叠或打开

  1. /*
  2.  * upper,上位机
  3.  * {
  4.  */

  5. #define    UPPER_DEVICE_COM            "/dev/ttySAC3"
  6. /* 串口数据接收线程(是上位机(pc)与 Real210开发板通信) */
  7. static    pthread_t    com_recv_threadid    = 0;        

  8. static    int32_t        upper_device_comfd = 0;        /* 与上位机通信的串口的描述符(PC机) */


  9. /* 串口的基本配置 */
  10. static     int32_t        _com_set_upper()
  11. {
  12.     int32_t    ret = 0;

  13. //    ret = __com_set(upper_device_comfd,B115200);
  14.     int32_t fd = upper_device_comfd;
  15.     struct termios opt;
  16. //    struct timeval start;
  17.     
  18.     tcgetattr(fd, &opt);
  19.     cfsetispeed(&opt, B115200);
  20.     cfsetospeed(&opt, B115200);
  21. //    cfsetispeed(&opt, baud_rate);
  22. //    cfsetospeed(&opt, baud_rate);

  23.     // 8n1
  24.     opt.c_cflag &= ~CSIZE;
  25.     opt.c_cflag &= ~CSTOPB;
  26.     opt.c_cflag &= ~PARENB;         // 无奇偶校验
  27.     opt.c_cflag |= CS8;

  28.     opt.c_cflag &= ~CRTSCTS;        // 没有使用硬件流控制
  29.     
  30. //    opt.c_cflag &= ~INPCK;
  31.     opt.c_cflag |= (CLOCAL | CREAD);                // Enable the receiver and set local mode

  32. //    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    // 原始数据
  33.     opt.c_lflag |= (ICANON | ECHO | ECHOE);    // 经典数据

  34.     opt.c_oflag &= ~OPOST;
  35.     opt.c_oflag &= ~(ONLCR | OCRNL);             // 添加的

  36.     opt.c_iflag &= ~(ICRNL | INLCR);
  37.     opt.c_iflag &= ~(IXON | IXOFF | IXANY);         // 没有软件流控制

  38.     tcflush(fd, TCIOFLUSH);

  39.     opt.c_cc[VTIME] = 1;    // 以 十分之一秒(1/10 s) 为单位
  40.     opt.c_cc[VMIN] = 0;

  41.     

  42.     if(tcsetattr(fd, TCSANOW, &opt) != 0 )
  43.     {
  44.            perror("tcsetattr error");
  45.            return -COM_CONFIG_ERROR;
  46.     }

  47.     return OPER_OK;
  48. }



  49. void*        com_recv_upper(void *param)
  50. {
  51.     uint8_t        recv_buffer[COM_BUFFER_SIZE] = {0};    
  52.     int32_t        len    = 0;
  53.     
  54.     while(1)
  55.     {
  56.         if(upper_device_comfd > 0)
  57.         {
  58.             memset(recv_buffer,0,sizeof(recv_buffer));
  59.             len = read(upper_device_comfd,recv_buffer,sizeof(recv_buffer));

  60.             if(len > 0)    printf("com recv thread : %s\n",recv_buffer);
  61.         }
  62.         else    // 串口异常或是关闭了
  63.         {
  64.             break;
  65.         }
  66.     }

  67.     pthread_exit(0);
  68.     //用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占用的资源不会随着线程的终止而得到释放

  69.     return NULL;
  70. }




  71. /* 串口的初始化 */
  72. int32_t        com_init_upper(void *param)
  73. {
  74.     int32_t    ret = 0;

  75.      ;

  76.     upper_device_comfd = open(UPPER_DEVICE_COM,O_RDWR | O_NOCTTY | O_NDELAY);    
  77.     if(upper_device_comfd< 0)
  78.     {
  79.         ret = -COM_OPEN_ERROR;
  80.     }
  81.     else
  82.     {
  83.         if((ret = _com_set_upper()) == OPER_OK)
  84.         {
  85.             if((ret = pthread_create(&com_recv_threadid,NULL,com_recv_upper,NULL))!= 0)
  86.                 ret = -THREAD_CREATE_ERROR;
  87.         }
  88.     }


  89.     return ret;
  90. }



  91. /* 串口的发送
  92.  * 返回值: 正常返回发送的字节数,0表示没有数据需要发送。
  93.  *            -1表示异常,也可通过errno获取异常码.
  94.  */
  95. int32_t        com_send_upper(uint8_t *send_buffer,int32_t buffer_len)
  96. {
  97.     int32_t    ret = 0;

  98.     // 疑问1:发送数据的长度是否需要判断有效值,有效值是多少??
  99.     
  100.     ret = write(upper_device_comfd, send_buffer, buffer_len);

  101.     return ret;
  102. }


  103. /* 串口参数设置
  104.  * 波特率,停止位,校验位,流控制,异步同步等
  105.  */
  106. int32_t        com_set_upper(void *param)
  107. {
  108.     int32_t    ret = 0;


  109.     return ret;
  110. }



  111. /* 串口设置参数生效 */
  112. int32_t        com_set_effect_upper(void *param)
  113. {
  114.     int32_t    ret = 0;


  115.     return ret;
  116. }



  117. /* 串口关闭*/
  118. int32_t        com_close_upper(void *param)
  119. {
  120.     int32_t    ret = 0;

  121.     if(upper_device_comfd > 0 )
  122.     {
  123.         close(upper_device_comfd);
  124.         upper_device_comfd = 0;
  125.     }

  126.     return ret;
  127. }




  128. /* 串口接收线程关闭 */
  129. int32_t        com_recv_thread_close(void *param)
  130. {
  131.     int32_t    ret = 0;

  132.     pthread_join(com_recv_threadid,NULL);

  133.     return ret;
  134. }

  135. /*
  136.  * upper,上位机
  137.  * }
  138.  */

    (3) 测试

点击(此处)折叠或打开

  1. void     test_com()
  2. {
  3.     printf("hello\n");

  4.     com_init_upper(NULL);
  5.     while(1);
  6. }


二,操作结果
    (1) pc上输入终端,在 SecureCRT 5.2 中 按下 Enter 键,会显示为 ^M。
    

    (2) pc上显示终端。
    






阅读(853) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~