免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: js001sdx
打印 上一主题 下一主题

[C] linux多线程问题求助!! [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-03-11 15:09 |只看该作者
回复 8# happy_fish100

感谢你的提醒!!
加上对nread的判断后!!单独跑的错误率比原来低些了!!
但在线程里基本没什么变化!!

论坛徽章:
0
12 [报告]
发表于 2010-03-11 15:17 |只看该作者
以前做个一个类似的项目,LED,LCD,KEYBOARD,GPIO,RS232
1,丢数据的可能原因:
  一,线程调度有问题, ...
消失的地平線 发表于 2010-03-11 15:03



    觉得你的分析很有可能。我也一直在找这类原因,但因为刚接触线程,对线程的了解还很浅,所以一直没有头绪!!
另外贴一下我的串口初始化代码:
#define SERIAL1     "/dev/ttyAT1"   //CONNECT TO MCU FOR PS2 KEYBOARD
#define SERIAL2     "/dev/ttyAT2"
#define SERIAL3     "/dev/ttyAT3"

static int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1800, B1200, B600, B300};
static int name_arr[]  = {230400,  115200,  57600,  38400,  19200,  9600,  4800,  2400,  1800,  1200,  600,  300};

int set_speed(int fd, int speed)
{
    int   i;
    int   status;
    struct termios   Opt;
    tcgetattr(fd, &Opt);

    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
    {
        if (speed == name_arr)
        {     
            tcflush(fd, TCIOFLUSH);     
            cfsetispeed(&Opt, speed_arr);  
            cfsetospeed(&Opt, speed_arr);   
            status = tcsetattr(fd, TCSANOW, &Opt);  
            /*if  (status != 0)
            {        
                perror("tcsetattr fd");  
                return -1;     
            }*/
            tcflush(fd,TCIOFLUSH);   
            return 0;
        }  
    }
    return -1;
}

int set_other_attribute(int fd, int databits, int stopbits, int parity)
{
    struct termios options;

    if (tcgetattr(fd, &options) != 0)
    {
        perror("SetupSerial 1");     
        return -1;  
    }
    options.c_cflag &= ~CSIZE;
    switch (databits)
    {   
        case 7:     
            options.c_cflag |= CS7;
            break;
        case 8:     
            options.c_cflag |= CS8;
            break;   
        default:   
            fprintf(stderr,"Unsupported data size\n");
            return -1;  
    }
    switch (parity)
    {   
        case 'n':
        case 'N':   
            options.c_cflag &= ~PARENB;   
            options.c_iflag &= ~INPCK;     
            break;  
        case 'o':   
        case 'O':   
        case 1:
            options.c_cflag |= (PARODD | PARENB);
            options.c_iflag |= INPCK;           
            break;  
        case 'e':  
        case 'E':   
        case 2:
            options.c_cflag |= PARENB;      
            options.c_cflag &= ~PARODD;
            options.c_iflag |= INPCK;      
            break;
        case 'S':
        case 's':   
        case 0:
            options.c_cflag &= ~PARENB;
            options.c_cflag &= ~CSTOPB;
            break;  
        default:   
            fprintf(stderr,"Unsupported parity\n");   
            return -1;  
    }  
    switch (stopbits)
    {   
        case 1:   
            options.c_cflag &= ~CSTOPB;  
            break;  
        case 2:   
            options.c_cflag |= CSTOPB;  
            break;
        default:   
            fprintf(stderr,"Unsupported stop bits\n");  
            return -1;
    }
    options.c_cflag &= ~CRTSCTS;
   
    if (parity != 'n')   
        options.c_iflag |= INPCK;
    tcflush(fd,TCIFLUSH);
   
    options.c_oflag = 0;
    options.c_lflag = 0;  
    options.c_cc[VTIME] = 150;
    options.c_cc[VMIN] = 0;

if (tcsetattr(fd,TCSANOW,&options) != 0)   
    {
        perror("SetupSerial 3");   
        return -1;  
    }

#if 0   
    tcgetattr(fd, &options);
    printf("c_iflag: %x\rc_oflag: %x\n", options.c_iflag, options.c_oflag);
    printf("c_cflag: %x\nc_lflag: %x\n", options.c_cflag, options.c_lflag);
    printf("c_line: %x\nc_cc[VTIME]: %d\nc_cc[VMIN]: %d\n", options.c_line, options.c_cc[VTIME], options.c_cc[VMIN]);
#endif
    return 0;  
}

论坛徽章:
0
13 [报告]
发表于 2010-03-11 15:20 |只看该作者
回复 10# 消失的地平線


    按照各位的提醒,已经加上了对nread 的判断!!但是在线程中任然存在相同的问题!!

论坛徽章:
0
14 [报告]
发表于 2010-03-11 15:47 |只看该作者

  1. #define SERIAL1     "/dev/ttyAT1"   //CONNECT TO MCU FOR PS2 KEYBOARD
  2. #define SERIAL2     "/dev/ttyAT2"
  3. #define SERIAL3     "/dev/ttyAT3"

  4. static int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1800, B1200, B600, B300};
  5. static int name_arr[]  = {230400,  115200,  57600,  38400,  19200,  9600,  4800,  2400,  1800,  1200,  600,  300};

  6. int set_speed(int fd, int speed)
  7. {
  8.     int   i;
  9.     int   status;
  10.     struct termios   Opt;
  11.     [color=Red]tcgetattr(fd, &Opt); /**/[/color]

  12.     for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
  13.     {
  14.         if (speed == name_arr)
  15.         {     
  16.             tcflush(fd, TCIOFLUSH);     
  17.             cfsetispeed(&Opt, speed_arr);  
  18.             cfsetospeed(&Opt, speed_arr);   
  19.             status = tcsetattr(fd, TCSANOW, &Opt);  
  20.             /*if  (status != 0)
  21.             {        
  22.                 perror("tcsetattr fd");  
  23.                 return -1;     
  24.             }*/
  25.             tcflush(fd,TCIOFLUSH);   
  26.             return 0;
  27.         }  
  28.     }
  29.     return -1;
  30. }

  31. int set_other_attribute(int fd, int databits, int stopbits, int parity)
  32. {
  33.     struct termios options;

  34.     if (tcgetattr(fd, &options) != 0)
  35.     {
  36.         perror("SetupSerial 1");     
  37.         return -1;  
  38.     }
  39.     options.c_cflag &= ~CSIZE;
  40.     switch (databits)
  41.     {   
  42.         case 7:     
  43.             options.c_cflag |= CS7;
  44.             break;
  45.         case 8:     
  46.             options.c_cflag |= CS8;
  47.             break;   
  48.         default:   
  49.             fprintf(stderr,"Unsupported data size\n");
  50.             return -1;  
  51.     }
  52.     switch (parity)
  53.     {   
  54.         case 'n':
  55.         case 'N':   
  56.             options.c_cflag &= ~PARENB;   
  57.             options.c_iflag &= ~INPCK;     
  58.             break;  
  59.         case 'o':   
  60.         case 'O':   
  61.         case 1:
  62.             options.c_cflag |= (PARODD | PARENB);
  63.             options.c_iflag |= INPCK;           
  64.             break;  
  65.         case 'e':  
  66.         case 'E':   
  67.         case 2:
  68.             options.c_cflag |= PARENB;      
  69.             options.c_cflag &= ~PARODD;
  70.             options.c_iflag |= INPCK;      
  71.             break;
  72.         case 'S':
  73.         case 's':   
  74.         case 0:
  75.             options.c_cflag &= ~PARENB;
  76.             options.c_cflag &= ~CSTOPB;
  77.             break;  
  78.         default:   
  79.             fprintf(stderr,"Unsupported parity\n");   
  80.             return -1;  
  81.     }  
  82.     switch (stopbits)
  83.     {   
  84.         case 1:   
  85.             options.c_cflag &= ~CSTOPB;  
  86.             break;  
  87.         case 2:   
  88.             options.c_cflag |= CSTOPB;  
  89.             break;
  90.         default:   
  91.             fprintf(stderr,"Unsupported stop bits\n");  
  92.             return -1;
  93.     }
  94.     options.c_cflag &= ~CRTSCTS;
  95.    
  96.     if (parity != 'n')   
  97.         options.c_iflag |= INPCK;
  98.     tcflush(fd,TCIFLUSH);
  99.    
  100.     options.c_oflag = 0;
  101.     options.c_lflag = 0;  
  102.    [color=Red] options.c_cc[VTIME] = 150;/*15s ??*/[/color]
  103.     options.c_cc[VMIN] = 0;

  104. if (tcsetattr(fd,TCSANOW,&options) != 0)   
  105.     {
  106.         perror("SetupSerial 3");   
  107.         return -1;  
  108.     }

  109. #if 0   
  110.     tcgetattr(fd, &options);
  111.     printf("c_iflag: %x\rc_oflag: %x\n", options.c_iflag, options.c_oflag);
  112.     printf("c_cflag: %x\nc_lflag: %x\n", options.c_cflag, options.c_lflag);
  113.     printf("c_line: %x\nc_cc[VTIME]: %d\nc_cc[VMIN]: %d\n", options.c_line, options.c_cc[VTIME], options.c_cc[VMIN]);
  114. #endif
  115.     return 0;  
  116. }
复制代码
这是我的疑问;
1 是检测是否读取到了配置;
2 如果没记错的话 VTIME单位是1/10s 150太大了;
3,选择了VTIME VMIN 那么意味着你将使用阻塞模式来操作VART,那么OPEN是设备时的对选项O_NDELAY的操作

论坛徽章:
0
15 [报告]
发表于 2010-03-12 10:15 |只看该作者
顺便想问下,你这串口读数据是怎么跳出大循环的。。。

论坛徽章:
0
16 [报告]
发表于 2010-03-12 10:17 |只看该作者
不好意思,没看清楚代码。。。

论坛徽章:
0
17 [报告]
发表于 2010-03-12 10:32 |只看该作者
顺便想问下,你这串口读数据是怎么跳出大循环的。。。
ferris2005 发表于 2010-03-12 10:15



    在数据流里收到0x16时,跳出循环的!!

论坛徽章:
0
18 [报告]
发表于 2010-03-12 10:40 |只看该作者
数据流里面0x16不是退出while(read)么?

论坛徽章:
0
19 [报告]
发表于 2010-03-12 11:47 |只看该作者
数据流里面0x16不是退出while(read)么?
ferris2005 发表于 2010-03-12 10:40



    谢谢你!!我传程序上来时没有while(read),后面在各位的提醒下,加上了while(read),但是忘记把while(1)去掉了,非常不好意思!!现在我已经把while(1)去掉了!!

论坛徽章:
0
20 [报告]
发表于 2010-03-12 13:28 |只看该作者
这是我的疑问;
1 是检测是否读取到了配置;
2 如果没记错的话 VTIME单位是1/10s 150太大了;
3,选择了 ...
消失的地平線 发表于 2010-03-11 15:47


按照你的疑问,我正在仔细排查我的串口初始化!!不过我觉的现在的问题主要是线程切换机制问题吧!!因为我的串口部分单独跑过没啥问题!!偶尔会有收错的情况,但大部分是能收对的,主要是一把这部分合到大程序里,单独做线程就不行了!!
我会把近期的调试结果,尽可能详细的发上来,请大家指教!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP