gpt4 book ai didi

c - 对于可以在编译时允许的可变大小的通用队列实现有什么想法吗?

转载 作者:太空宇宙 更新时间:2023-11-04 03:48:55 25 4
gpt4 key购买 nike

我在我的系统中使用了 3 个不同的 UART。我为要放置的 RX 数据和 TX 数据定义了一个软件缓冲区。

/*! Queue Size for all UARTS. Defines the size of static memory allocated for
RX and TX Buffers. */
#define QUEUE_SIZE 300u

/*!
* \brief Arbitrary FIFO queue structure used to store RAW serial data
* \ingroup uart
*/
typedef struct
{
uchar8_t x[QUEUE_SIZE];
uint16_t head_index;
uint16_t tail_index;
uint16_t length;
} serial_queue_t;

我声明了该结构的 6 个实例 - 每个 UART 都有一个 RX 和 TX 缓冲区。

现在我有一个通用方法可以从 UART 拉出一个字符或将一个字符推送到 UART。

/*!
* \brief Private method used to get and remove the next character in an
* arbitrary UART FIFO queue.
* \ingroup uart
* \param[in] *p_queue The queue to get data from
* \param[out] *p_pull The next character in the buffer. This will not be
* assigned if the character is unavailable.
* \returns TRUE if the next character is available, FALSE if that character is
* not available.
*
* \note This Function is Atomic
* If this function is executing and a UART ISR occurs which would recall this
* function before the tail index has been updated it could cause a memory
* leak/data loss. Therefore this function is not reentrant and must block
* interrupts.
*/
static bool_t uart_pull(serial_queue_t volatile * p_queue, uchar8_t * p_pull);

/*!
* \brief Private method to push a character onto an arbitrary UART queue.
* \ingroup uart
* \param[in,out] *p_queue The queue to push data onto.
* \param[in] push The next character in the buffer. This will not be assigned
* if the character is unavilable.
* \returns TRUE if the character was placed in the queue successfully, FALSE
* if the queue is full.
*
* \note This Function is Atomic
* If this function is executing and a UART ISR occurs which would recall this
* function before the head index has been updated it could cause a memory
* leak/data loss. Therefore this function is not reentrant and must block
* interrupts.
*/
static bool_t uart_push(serial_queue_t volatile * p_queue, uchar8_t push);

现在我需要更改我的实现。我需要调整一些缓冲区的大小,使它们更大,以便我可以传输更大的数据帧。我还计划缩小一些缓冲区以回收一些空间,因为 300 字节对它们来说太大了。我正在尝试想出一种干净的方法来执行此操作,以便我可以使我的实现保持通用。

到目前为止,我最好的想法是简单地定义几个不同的结构,每个结构都定义一个不同的数组,每个数组的大小都不同,然后使 p_queue 指针无效。我可以为这些函数中的每一个添加一个参数,该参数可以告诉函数正在使用哪个 UART 缓冲区,以便它们知道在处理缓冲区时使用哪个结构,或者向存储该队列的 max_length 的队列结构添加另一个字段,将max_length、head_index、tail_index移到字符数组的前面。

任何人都有更好的想法 - 因为为几乎相同的东西定义多达 6 个不同的结构不是那么干净吗?我不想将整个事情都放在堆上并分配运行时 - 我希望在编译时由链接器处理分配。

最佳答案

我正在使用来自 Adam Dunkels ContikiOS 的环形缓冲区:http://contiki.sourceforge.net/docs/2.6/a01686.html

我不得不对它们进行一些修改以获得我想要的东西,但作为一个构建平台,它是坚如磐石的。

我已经替换了 intint32_t来自 <stdint.h>等等,以确保我有一个可移植的实现。除此之外,我认为我没有太大改变。我在具有不同字长、字节序等的各种不同处理器上使用该代码。它只是工作 (TM) :)

编辑:重新阅读您的问题后,您确定要在编译时 而不是在运行时 更改大小吗?编译时很容易,运行时通常意味着动态分配或至少是一个带有一些自制分配器的公共(public)内存缓冲区。

关于c - 对于可以在编译时允许的可变大小的通用队列实现有什么想法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22203704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com