2014-02-05 39 views
0

我正在寫一個多線程通信接口,其中一個函數(在我的主線程中)將數據推入隊列(VxWorks msgQLib),並在我的通信任務中提供另一個函數,從隊列中提取數據以轉發到硬件接口。 現在,我的推送數據似乎不符合我的提取數據(反之亦然)。我插入了一些調試信息來了解發生了什麼,但迄今未能找到罪魁禍首。我有的代碼:爲什麼我推入隊列的數據不會在另一端出現?

有點解釋。我構建了這樣的函數,以便在實際消息之前插入帶有一些元數據的消息標記,即每條消息都會將兩個項插入到隊列中。 請不要擔心「回覆」部分,但仍需要雙方的一些工作。我現在只是擔心等式中即將離任的部分。

是推動數據到隊列(在應用程序的任務)的函數:

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 

我不明白爲什麼我的數據進入排隊不會出來...

+0

@nos非常真實的,立即修復此問題! – cerr

回答

1

請檢查你調用的函數的所有返回值,所以你至少不要錯過任何錯誤。例如你正在收到NO_WAIT的消息,所以如果你在發送任何東西之前碰巧打電話給msgQReceive,你將不會收到任何東西 - 這是一件很重要的事情。與NO_WAIT一起發送時類似 - 如果隊列已滿,則不處理該情況。

但是,您的發送功能有:

UINT8 *msgTag[MSGTAGLEN] 

由於某種原因是UINT8指針數組。代碼中沒有任何內容表明這應該是一個指針數組,並且由於數組在接收函數中有所不同,因此您將在兩個函數中完全不同地解釋這些字節。您接收功能似乎有它正確的,所以一定要確保發送功能也具有相同的:

UINT8 msgTag[MSGTAGLEN]; 

(還要確保您在這裏兩個功能arn't從幾個任務調用,它具有靜態變量和不線程安全,不可重入。)

+0

哎唷!是的,我沒有看到那個'*',討厭的!但很好,趕快,謝謝!我還包括了現在對返回值的檢查... – cerr

+0

關於此問題還有一件事:我定義了靜態函數,以便從「外部」沒有其他人能夠訪問這些函數。如果他們在自己的任務中運行,並且隊列是唯一的連接,那麼線程安全是成立的,不是嗎?來自〜VxWorks的'msgQLib'是線程安全的:http://www.vxdev.com/docs/vx55man/vxworks/ref/msgQLib.html#msgQReceive – cerr

+1

@cerr是的,只要有一個任務調用它們在任何給定時間都可以運行,沒關係 – nos

相關問題