簡體   English   中英

如何在標准 C 中實現消息隊列

[英]How to implement a message queue in standard C

我有一個項目(使用 c 代碼的微控制器 STM32),我需要從串口接收消息(例如字符串),我需要將消息放入隊列中,稍后我將讀取字符串。

有人能告訴我在哪里可以找到一些關於如何使用標准 C創建字符串(或字節數組)的消息隊列(如 FIFO)以及如何管理隊列的示例嗎? 感謝任何形式的支持。

  • “關於如何使用標准 C 創建字符串(或字節數組)的電子消息隊列(如 FIFO)以及如何管理隊列的示例”

  • “在具有標准 C 的微控制器中,您應該管理緩沖區、創建隊列、將元素入隊和出隊”

下面給出的例子應該滿足要求。

如有必要,使用的庫函數可以很容易地替換為特定於平台的版本或標准 C 數組操作。

隊列的內存分配也可以作為靜態變量而不是堆棧變量來完成。 如果需要,甚至可以使用malloc

消息類型可以很容易地擴展。 隊列和數據大小被定義為常量。

@leonardo 對如何構建處理給出了很好的提示,即在中斷例程中將消息入隊並在主程序中將它們出隊。 我想需要使用某種信號量,這樣操作隊列的函數的執行就不會混淆。 信號量中討論了一些關於此的想法,例如 ISR(中斷服務例程)中的同步

/*
Portable array-based cyclic FIFO queue.
*/

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define MESSAGE_SIZE 64
#define QUEUE_SIZE 3

typedef struct {
char data[MESSAGE_SIZE];
} MESSAGE;

typedef struct {
    MESSAGE messages[QUEUE_SIZE];
    int begin;
    int end;
    int current_load;
} QUEUE;

void init_queue(QUEUE *queue) {
    queue->begin = 0;
    queue->end = 0;
    queue->current_load = 0;
    memset(&queue->messages[0], 0, QUEUE_SIZE * sizeof(MESSAGE_SIZE));
}

bool enque(QUEUE *queue, MESSAGE *message) {
    if (queue->current_load < QUEUE_SIZE) {
        if (queue->end == QUEUE_SIZE) {
            queue->end = 0;
        }
        queue->messages[queue->end] = *message;
        queue->end++;
        queue->current_load++;
        return true;
    } else {
        return false;
    }
}

bool deque(QUEUE *queue, MESSAGE *message) {
    if (queue->current_load > 0) {
        *message = queue->messages[queue->begin];
        memset(&queue->messages[queue->begin], 0, sizeof(MESSAGE));
        queue->begin = (queue->begin + 1) % QUEUE_SIZE;
        queue->current_load--;
        return true;
    } else {
        return false;
    }
}

int main(int argc, char** argv) {
    QUEUE queue;
    init_queue(&queue);

    MESSAGE message1 = {"This is"};
    MESSAGE message2 = {"a simple"};
    MESSAGE message3 = {"queue!"};

    enque(&queue, &message1);
    enque(&queue, &message2);
    enque(&queue, &message3);

    MESSAGE rec;

    while (deque(&queue, &rec)) {
        printf("%s\n", &rec.data[0]);
    }
}

編譯和運行:

$ gcc -Wall queue.c
$ ./a.out          
This is
a simple
queue!
$ 

C 語言沒有內置隊列(它是一種不包括電池的語言),您需要自己構建。 如果您只需要一個 FIFO 將內容推送到您的中斷例程中,然后將它們彈出到您的主循環中(順便說一句,這是一個很好的設計),請檢查A Simple Message Queue for C如果這對您有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM