缓冲 UART RX 传入数据的最佳方式是什么?
which is the best way to buffering UART RX incoming data?
我正在使用连接到我的微控制器的 GSM 调制解调器来执行 send/receive AT 命令,而且我正在使用 MQTT 执行与远程服务器的连接。
经过一些研究,我制作了自己的 UART AT 命令解析器实现来接收和发送命令,它几乎一直工作正常,但我想要质量更好的代码,我认为我实现它的方式可能是有点粗糙
我在下面的代码中添加了一个模拟 "UART" 以便更好地理解我在做什么,它不能 100% 正常工作因为是一个模拟
我的问题是:如何改进下面的代码?使用 UART 接收传入数据并创建自己的缓冲区的最佳做法是什么?
代码
#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;
}
}
实现循环缓冲区
循环缓冲区、循环队列、循环缓冲区或环形缓冲区是一种数据结构,它使用单个固定大小的缓冲区,就好像它是端到端连接的一样。这种结构很容易用于缓冲数据流。
那是来自维基百科。如何实施?您需要一个指向队列头的指针或索引,另一个指向队列尾部。您还可以跟踪队列的长度和头部或尾部。然后头部或尾部离开缓冲区,它更改为它的开头
我正在使用连接到我的微控制器的 GSM 调制解调器来执行 send/receive AT 命令,而且我正在使用 MQTT 执行与远程服务器的连接。
经过一些研究,我制作了自己的 UART AT 命令解析器实现来接收和发送命令,它几乎一直工作正常,但我想要质量更好的代码,我认为我实现它的方式可能是有点粗糙
我在下面的代码中添加了一个模拟 "UART" 以便更好地理解我在做什么,它不能 100% 正常工作因为是一个模拟
我的问题是:如何改进下面的代码?使用 UART 接收传入数据并创建自己的缓冲区的最佳做法是什么?
代码
#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;
}
}
实现循环缓冲区 循环缓冲区、循环队列、循环缓冲区或环形缓冲区是一种数据结构,它使用单个固定大小的缓冲区,就好像它是端到端连接的一样。这种结构很容易用于缓冲数据流。
那是来自维基百科。如何实施?您需要一个指向队列头的指针或索引,另一个指向队列尾部。您还可以跟踪队列的长度和头部或尾部。然后头部或尾部离开缓冲区,它更改为它的开头