c - 为什么我插入队列的数据没有从另一端出来?

标签 c multithreading queue fifo vxworks

我正在编写一个多线程通信接口(interface),其中一个函数(在我的主线程中)将数据推送到队列(VxWorks msgQLib),而我的通信任务中的另一个函数从队列中获取数据以转发到硬件接口(interface)。 现在,似乎我的推送数据与我的获取数据不一致(反之亦然)。我插入了一些调试消息来找出发生了什么,但到目前为止尚未找到罪魁祸首。我的代码:

一点解释。我构建了这些函数,以便在实际消息之前插入带有一些元数据的消息标记,即每条消息都会将两个项目插入队列中。 请先不要担心“回复”部分,双方都还需要做一些工作。我现在只是担心方程的输出部分。

将数据推送到队列的函数(在应用程序任务中):

static STATUS SPIQWriteRead_TDM(UINT8 cmdlen, UINT8 *cmd, UINT8 retdatlen, UINT8 *retdat)
{
    UINT8 BytesRead;
    UINT8 *msgTag[MSGTAGLEN]={0};
    static UINT spi_init = 0;
    UINT i=0;

    //assemble message tag
    msgTag[0] = 0x01; //FrameID
    msgTag[1] = cmdlen/255; //MsgLen MSB
    msgTag[2] = cmdlen%255; //MsgLen LSB
    msgTag[3] = CS_TDM; // ChipSelect
    msgTag[4] = 0; //SlotID


    //copy message tag into queue
    for(i=0;i<MSGTAGLEN;i++)
            printf("<= msgTag[%d] 0x%x\n",i,msgTag[i]);
    msgQSend(TDMTxQ,msgTag,MSGTAGLEN,NO_WAIT,MSG_PRI_NORMAL);
    printf("<= TxQueue(0x%x) contains %d items\n",TDMTxQ, msgQNumMsgs(TDMTxQ));

    for(i=0;i<cmdlen;i++)
        printf("<= msg[%d] 0x%x\n",i,cmd[i]);
    // copy message into queue
    msgQSend(TDMTxQ,cmd,cmdlen,NO_WAIT,MSG_PRI_NORMAL);
    printf("<= TxQueue(0x%x) contains %d items\n",TDMTxQ, msgQNumMsgs(TDMTxQ));

    // wait for a maximum of 10 ticks (~1600ms) for the Reply
    BytesRead = msgQReceive(TDMRxQ,retdat,retdatlen,100);
    for(i=0;i<retdatlen;i++)
            printf("retdat[%d] 0x%x\n",i,retdat[i]);
    printf("BytesRead 0x%x\n",BytesRead);
    // compare reply and return
    if (BytesRead != retdatlen)
        return ERROR;
    else
        return OK;
}

以及从队列中获取数据的函数(在通信任务中):

static FROM_Q_DAT *GetFromQueue(MSG_Q_ID TxQId)
{
    UINT8 msgTag[MSGTAGLEN]= {0};
    UINT8 FrameID = 0;
    UINT16 MsgLen = 0;
    UINT8 ChipSelect = 99;
    UINT8 SlotID = 99;
    static UINT8 *cmd=NULL;
    UINT8 retdat[2]={0};
    UINT8 cs=99;
    static FROM_Q_DAT Qdat;
    int retval = 0;
    UINT8 i=0;

    // read message tag from queue
    msgQReceive(TxQId, msgTag, MSGTAGLEN, NO_WAIT);
    for(i=0;i<MSGTAGLEN;i++)
            printf("=> msgTag[%d] 0x%x\n",i,msgTag[i]);

    // parse received message tag 
    FrameID = msgTag[0];
    MsgLen = (((UINT16)msgTag[1])<<8) | (msgTag[2]);
    ChipSelect = msgTag[3];
    SlotID = msgTag[4];
    printf("FrameID: %d\n",FrameID);
    printf("MsgLen: %d\n",MsgLen);
    printf("ChipSelect: %d\n",ChipSelect);
    printf("SlotID: %d\n",SlotID);

    printf("=> TxQueue(0x%x) contains %d items\n",TxQId, msgQNumMsgs(TxQId));

    cmd = (UINT8*) calloc(MsgLen, sizeof(UINT8));
    // Get the message from the queue 
    msgQReceive(TxQId, cmd, MsgLen, NO_WAIT);
    for(i=0;i<MsgLen;i++)
                printf("=> cmd[%d] 0x%x\n",i,cmd[i]);

    printf("=> TxQueue(0x%x) contains %d items\n",TxQId, msgQNumMsgs(TxQId));

    Qdat.cs = ChipSelect;
    Qdat.len = MsgLen;
    Qdat.data = cmd;
    return &Qdat;
}

屏幕截图如下所示:

<= msgTag[0] 0x1
<= msgTag[1] 0x0
<= msgTag[2] 0x9
<= msgTag[3] 0x2
<= msgTag[4] 0x0
<= TxQueue(0x261c6010) contains 1 items
<= msg[0] 0x5e
<= msg[1] 0x8
<= msg[2] 0x40
<= msg[3] 0x6
<= msg[4] 0x0
<= msg[5] 0x0
<= msg[6] 0x0
<= msg[7] 0x0
<= msg[8] 0x0
<= TxQueue(0x261c6010) contains 2 items
//the next message (with '==' is from the communication engine that checks for content in the communication Queue:
== TxQueue(1) contains 2 items
=> msgTag[0] 0x0
=> msgTag[1] 0x0
=> msgTag[2] 0x0
=> msgTag[3] 0x1
=> msgTag[4] 0x0
FrameID: 0
MsgLen: 0
ChipSelect: 1
SlotID: 0
=> TxQueue(0x261c6010) contains 1 items
=> TxQueue(0x261c6010) contains 0 items

我不明白为什么进入队列的数据不会出来......

最佳答案

请检查您调用的函数的所有返回值,这样您至少不会错过任何错误。例如您正在使用 NO_WAIT 接收消息,因此,如果您在发送任何内容之前碰巧调用 msgQReceive ,您将不会收到任何内容 - 这将是需要处理的重要事情。与使用 NO_WAIT 发送时类似 - 如果队列已满,您不会处理这种情况。

但是,您的发送功能有:

 UINT8 *msgTag[MSGTAGLEN]

出于某种原因,这是一个 UINT8 指针数组。代码中没有任何内容表明这应该是一个指针数组 - 并且由于接收器函数中的数组不同,因此您将在两个函数中以完全不同的方式解释字节。您的接收器函数似乎正确,因此请确保发送器函数也具有相同的:

 UINT8 msgTag[MSGTAGLEN];

(还要确保这里的两个函数不是从多个任务中调用的,它具有静态变量并且不是线程安全的,并且不可重入。)

关于c - 为什么我插入队列的数据没有从另一端出来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21590455/

相关文章:

iphone - cancelPreviousPerformRequestWithTarget 不会取消我之前使用 PerformSelector 启动的延迟线程

C++队列存储多种类型对象

python - 如何加快多处理队列的同时读写速度?

c++ - 省略号函数参数的字节大小

c++ - 如何添加退出窗口事件?

c - main 和 fopen 是有效的变量名吗?

c++ - 迭代器声明 : "does not contain a type"

c - "Uninitialized Local Variable"错误,尽管定义了变量?

java - 将 2 方法与另一个方法同步,但彼此之间不同步

multithreading - 使用 OMP 循环展开