I have a project (micro controller STM32 using c code) where I need to receive messages from serial port (for example strings) and I need to put the messages in a queue where I will read the string later.
Can someone tell me where can I find some example on how to create a message queue (like FIFO) of strings (or byte array) using standard C and how to manage the queue? Thanks for any kind of support.
"example on how to create e message queue (like FIFO) of strings (or byte array) using standard C and how to manage the queue"
"in a micro controller with a standard C you should manage the buffers, create the queue, enqueue and dequeue the elements"
The example given below should meet the requirements.
If necessary, the library functions used can easily be replaced with platform-specific versions or standard C array operations.
The memory allocation for the queue can also be done as static variable instead of as stack variable. If desired, even malloc
could be used.
The message type can easily be extended. The queue and data sizes are defined as constants.
@leonardo gave a good hint on how to structure the processing, i.e. enqueuing messages in an interrupt routine and dequeuing them on main. I guess that some kind of semaphore needs to be used so that the execution of functions which manipulate the queue don't get mixed up. Some thoughts on this are discussed in semaphore like synchronization in ISR (Interrupt service routine)
/*
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]);
}
}
Compiling and running:
$ gcc -Wall queue.c
$ ./a.out
This is
a simple
queue!
$