I am using a GSM modem attached to my microcontroller, to send/receive AT commands, also I am performing connection to a remote server using MQTT.
after some research I made my own UART AT command parser implementation to receive and send commands it is working almost fine all the time, but I would like a better quality code, I think the way I implementing it could be a little rough
I added a simulated "UART" on the code below to give a better understanding what I am doing, it is not working 100% fine because is a simulation
My question is: how can I improve the code below? what are the best practices for receiving incoming data using UART and creating a own buffer?
code
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
static void at_wait_msg(char text);
static char _rx_data[512];
static uint16_t _rx_index = 0;
enum messagetype
{
CommandReceived = 0,
Buffering,
ReceivingMQTT
};
messagetype type;
int main()
{
char text[] = "\nAT\nOK\nAT\n0...readertesttagsample1000"; //example data getting from UART1
//0...readertesttagsample1000(hex format for MQTT 30 18 00 09 72 65 61 64 65 72 74 73 74 74 61 67 73 61 6D 70 6C 65 31 30 30 30
//pub:30
//total len 24
//topic len 9
//data the remaining bytes
for (int i = 0; i < strlen(text) + 1; i++)
at_wait_msg(text[i]); //to simulate getting data from UART1 byte per byte
return 0;
}
static void at_wait_msg(char text)
{
if (text == 0x0A)
{
type =CommandReceived;
}
if (text != 0x0A && type == Buffering)
{
type = Buffering;
}
if (text == 0x30)
{
type = ReceivingMQTT;
}
switch (type)
{
case Buffering:
_rx_data[_rx_index++] = text;
break;
case CommandReceived:
printf(" buffer[%s]\r", _rx_data);
memset(_rx_data, 0, _rx_index);
_rx_index = 0;
type = Buffering;
break;
case ReceivingMQTT:
printf(" buffer[%s]\r", _rx_data);
memset(_rx_data, 0, _rx_index);
_rx_index = 0;
type = Buffering;
break;
}
}
Implement circular buffer A circular buffer, circular queue, cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end. This structure lends itself easily to buffering data streams.
That was from Wikipedia. How to implement it? You need a pointer or index which points to the queue head and another one to the tail. You can also can keep track of the length and head or tail of the queue. Then the head or tail goes out of the buffer it changes to the start of it