【问题标题】:MultiThreading and Uart write多线程和 UART 写入
【发布时间】:2018-03-13 17:44:04
【问题描述】:

首先看下面的编辑部分。

我将 beaglebone black、ker 3.8 和 GCC 编译器用于信号处理项目。 我通过 uart 通信异步接收来自三个 GPS 模块的原始数据。因此,我使用了 3 个线程来连续检查 3 个 UART(BB-UART1、BB-UART2、BB-UART4)来接收原始数据,这里称为“读取线程”。从每个模块收到每个数据包后,我对收到的数据包进行解码并提取重要数据包。 当在线程中完成解码时,我在一个单独的线程中执行信号处理,称为“信号处理线程”,使用上述 3 个重要的解码数据包。 很明显,我应该将读取线程与信号处理线程同步。我为此使用 pthread_cond_wait 和 pthread_cond_signal。 代码运行良好,同步和信号处理高效执行。每个数据包在 0.1 秒内收到(每秒 10 次)。 在信号处理线程中,经过信号处理后,我将信号处理结果通过单独的UART,BB-UART5发送给用户。 当我添加这部分代码时,“THIS”行,一段时间后,所有部分或 OK 和信号处理结果都发送给用户,信号处理线程被冻结并锁定在互斥锁中。事实上,互斥锁解锁不是在上一步中执行的。 我花了很多时间,几个星期,来寻找原因。当我删除用于线程同步的互斥锁和其他工具(以使整个代码易于调试)时,某处的数据数组溢出并且其数据更改为溢出值。但是,当我不添加“THIS”行时,任何时候都不会发生溢出。 当我在信号处理线程中删除“写入”功能(BB-UART5)时,所有操作都正常。

信号处理线程:

void *signal_processing_thread (void *arg){

int i, j;
char str[512];

printf("000000000000000000000000000000000000000000\r\n");
printf("0-signal_processing_thread is running!\r\n");
printf("000000000000000000000000000000000000000000\r\n");

while(1){
    pthread_mutex_lock(&th1); // the code lock here after add "THIS" line
    pthread_mutex_lock(&th2);
    pthread_mutex_lock(&th3);

    if ((!decode_completed[0])|(!decode_completed[1])|(!decode_completed[2])){
        pthread_mutex_unlock(&th1);
        pthread_mutex_unlock(&th2);
        pthread_mutex_unlock(&th3);
        continue;
    }
    // data packets are ready in reading threads

    // signal processing start



    // signal processing done

    // send the results
    sprintf (str,"some string\r\n\0",some variables);
    printf (str);

    for (i=0;i<256;i++)
        if (str[i]==0)
             break;
    write (uart5_id, str, i); // "THIS" line

    decode_completed [0] = 0;
    decode_completed [1] = 0;
    decode_completed [2] = 0;

    pthread_cond_signal(&cv1);
    pthread_mutex_unlock(&th1);

    pthread_cond_signal(&cv2);
    pthread_mutex_unlock(&th2);         

    pthread_cond_signal(&cv3);
    pthread_mutex_unlock(&th3);
}

printf("signal processing thread is closed!\r\n");
}

阅读线程:

void *getdecodedata1_thread (void *arg){
    int ret, count, count_decode=0;
    char buffer[2024], buffer_decode[2024];
    int i;

    printf("1-getdecodedata_thread is running!\r\n");

    count = 0;

    pthread_mutex_lock(&th1);       
    while(1){
        for (i=0;i<500;i++){    
            ret = read(uart1_id, buffer+count ,255); 

            if (ret<1)
                continue;

            // data received

            count += ret;
            if (count>1000) break;              
        }
        if (count>0){ // packet received
            for (i=0;i<count;i++) 
                buffer_decode1[count_decode3+i]=buffer[i];

            count_decode1 += count;

            if (count_decode1>15){
                // decode
                // ....
                // decode done
            }
            count = 0;

        }
        if  (decode is completed) {     

            decode_completed [0] = 1; // newdata

            printf("WAIT_1\n");

            pthread_cond_wait(&cv1,&th1);
            pthread_mutex_unlock(&th1);
            pthread_mutex_lock(&th1);

            printf("RELEASE_1\n");
        }
    }
 }  
void *getdecodedata2_thread (void *arg){
    int ret, count, count_decode=0;
    char buffer[2024], buffer_decode[2024];
    int i;

    printf("2-getdecodedata_thread is running!\r\n");

    count = 0;

    pthread_mutex_lock(&th2);       
    while(1){
        for (i=0;i<500;i++){    
            ret = read(uart2_id, buffer+count ,255); 

            if (ret<1)
                continue;

            // data received

            count += ret;
            if (count>1000) break;              
        }
        if (count>0){ // packet received
            for (i=0;i<count;i++) 
                buffer_decode3[count_decode2+i]=buffer[i];

            count_decode2 += count;

            if (count_decode2>15){
                // decode
                // ....
                // decode done
            }
            count = 0;

        }
        if  (decode is completed) {     

            decode_completed [1] = 1; // newdata

            printf("WAIT_2\n");

            pthread_cond_wait(&cv2,&th2);
            pthread_mutex_unlock(&th2);
            pthread_mutex_lock(&th2);

            printf("RELEASE_2\n");
        }
    }
}

void *getdecodedata3_thread (void *arg){
    int ret, count, count_decode=0;
    char buffer[2024], buffer_decode[2024];
    int i;

    printf("3-getdecodedata_thread is running!\r\n");

    count = 0;

    pthread_mutex_lock(&th3);       
    while(1){
        for (i=0;i<500;i++){    
            ret = read(uart4_id, buffer+count ,255); 

            if (ret<1)
                continue;

            // data received

            count += ret;
            if (count>1000) break;              
        }
        if (count>0){ // packet received
            for (i=0;i<count;i++) 
                buffer_decode3[count_decode3+i]=buffer[i];

            count_decode3 += count;

            if (count_decode3>15){
                // decode
                // ....
                // decode done
            }
            count = 0;

        }
        if  (decode is completed) {     

            decode_completed [2] = 1; // newdata

            printf("WAIT_3\n");

            pthread_cond_wait(&cv3,&th3);
            pthread_mutex_unlock(&th3);
            pthread_mutex_lock(&th3);

            printf("RELEASE_3\n");
        }
    }
}

编辑:我发现问题出在代码的另一个地方。在某些地方我使用“写入”功能将一些字节发送到 UART5,并在一个单独的线程中我同时读取(非阻塞)UART5 以接收命令。我认为出现了“SegFault”之类的问题,并且看到了上述问题。当我评论 UART5 的“读取”功能时,一切正常,互斥锁工作正常。如何使用UART5同时读写?

【问题讨论】:

标签: multithreading overflow mutex uart


【解决方案1】:

大约 2 个月后,我发现问题源于 IC 中的无效事件。我使用 ttl 到 RS485 转换器,它的电源总线有总噪声和失真,这导致将一些无效字符发送到串行输入。事实上,当我使用串行输出发送一些字符时,我认为串行输入可能会收到一些无效数据。因此它将代码冻结在一种临界条件机制中。当我将IC与BBB分开时,问题就解决了。 我不知道为什么?如何?串行输入上的无效数据如何使关键条件锁定?我使用 ttyO[] 文件来读写串口。

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    相关资源
    最近更新 更多