嵌入式中緩衝區隊列的實現

來源:互聯網
上載者:User

在串口,IIC或SPI以及CAN等通訊中,往往需要一次性發送一幀完整的資料,由於硬體發送的速度問題,硬體不能及時發送出去,就會導致資料丟失等一系列問題。通常採用建立緩衝區解決。隊列可以有效利用緩衝區空間,並且保證資料在發送和接收過程中的時序問題。現在網上有公開的隊列源碼,其一般由入隊,出隊,查詢隊列成員數量,建立隊列,銷毀隊列等組成,相對比較完善,但是在串口等環境中使用存在過多的調用函數等問題。所以就以上的情況做出了改善,編寫了一個精簡的緩衝隊列,經過測試可以保證資料轉送的完整性。 一、建立結構體

結構體主要由 緩衝區,隊列頭指標,隊列尾指標,以及隊列發送完成標誌位組成。

/*******資料發送緩衝區 結構體*****/typedef struct {    u8 TxBuff[BUFFSIZE]; //緩衝區    u16 font;                        //頭指標    u16 rear;             //尾指標    u8 finished;         //發送完成,0代表未發送完,1代表發送完成,發送終止 }TxBuffer;
二 入隊函數

將發送的資料存入緩衝數組,並且移動相應長度的尾指標,檢查發送標誌位,判斷是否需要啟動硬體發送。主要有兩個函數,一個為單位元組發送個,另一個為多位元組發送。

/* *函數名:UsartSendData *描述:串口發送資料,發送單位元組 *輸入:tx:發送介面 *輸出:無 *調用:外部調用 */void UsartSendData(ConnIFName tx,u8 data,USART_TypeDef* u){        TxBuffer* buff = GetTxBuffer(tx);      //佔用1位元組用於判斷是否到達緩衝區尾部        if(buff->rear == BUFFSIZE) buff->rear=0;        buff->TxBuff[buff->rear++]=data;        if(buff->finished == 1)        {            buff->finished=0;            if(buff->font == BUFFSIZE) buff->font=0;            USART_SendData(u,buff->TxBuff[buff->font]);            buff->TxBuff[buff->font] = 0xFF;            buff->font++;        }}/* *函數名:MultitySend() *描述:串口發送資料,多位元組發送 *輸入:tx->發送介面 ;sendData[] 發送的數組;u->調用發送的硬體串口;len->發送的長度 *輸出:無 *調用:外部調用 */void MultitySend(ConnIFName tx,u8 data[],USART_TypeDef* u,u8 len){    u8 i=0;    TxBuffer* buff = GetTxBuffer(tx);    if(len<BUFFSIZE-buff->rear+buff->font)    {        for(i=0;i<len;i++)        {            if(buff->rear == BUFFSIZE) buff->rear=0;            buff->TxBuff[buff->rear++] = data[i];        }           if(buff->finished !=0)        {            if(buff->font == BUFFSIZE) buff->font=0;            USART_SendData(u,buff->TxBuff[buff->font++]);               buff->finished =0;        }    }}
三 出隊函數

讀取隊列中的資料並交由硬體發送,同時移動頭指標到相應位置,根據情況操作標誌位。這個函數一般由發送中斷調用。

/* *函數名:TxBuffIRQ *描述:串口發送 *輸入:tx:發送介面 *輸出:無 *調用:中斷調用 */void TxBuffIRQ(ConnIFName tx,USART_TypeDef* u){        //取得該通訊介面緩衝區指標        TxBuffer* buff = GetTxBuffer(tx);         //判斷緩衝區為NULL,則發送完成,停止發送        if(buff->font == buff->rear )           {            buff->finished=1;    //發送完成置位(緩衝區為空白)        }else        {        //判斷是否到達隊列尾部,如果到達則從頭開始        /**防止由於時間差的問題導致中斷重複發送緩衝區資料*****/            if(buff->font == BUFFSIZE ) buff->font=0;             USART_SendData(u,buff->TxBuff[buff->font]);            //0xff填充緩衝區            buff->TxBuff[buff->font] = 0xff;            buff->font++;        }}
四 擷取隊列函數

當多個隊列共存時,需要由該函數傳遞對應隊列的指標,以便操作隊列。

/* *函數名:GetTxBuffer *描述:取得發送緩衝區指標 *輸入:tx:取得哪個值 *輸出:無 *調用:內部調用 */TxBuffer* GetTxBuffer(ConnIFName tx){        switch (tx)        {            case DGUSIF:                return &DgusTxBuff;             case WKIF:                return &WKTxBuff;            case CK1IF:                return &CKTxBuff;            default:                break;        }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.