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

C 对于可以在编译时允许具有可变大小的通用队列实现,有什么想法吗?,c,uart,msp430,C,Uart,Msp430,我在我的系统中使用了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 * \in

我在我的系统中使用了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_队列指针无效。我可以为每个函数添加一个参数,它可以告诉函数正在使用哪个UART缓冲区,以便它们在处理缓冲区时知道要使用哪个结构,或者在队列结构中添加另一个字段来存储该队列的最大长度,并重新定位最大长度、头索引,以及字符数组前面的尾部索引


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

我正在使用Adam Dunkels ContikiOS提供的环形缓冲区:

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

我已经用
中的
int32\t
等替换了
int
,以确保我有一个可移植的实现。除此之外,我想我没什么变化。 我在各种不同的处理器上使用该代码,具有不同的字长、尾数等。它只起作用(TM):)

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

我不想在运行时这样做。现在我的实现只使用静态内存,我希望保持这种方式。我希望避免动态分配。我现在正在我的应用程序中使用堆,但我做得很节省。我把这个注释放进去是为了避免出现这样的建议:“只是在动态内存中抛出一个指针,在启动时得到malloc'ed”。好的,我正在查看您链接的这个实现。它看起来几乎与我的操作方式完全相同,只是数据是与管理结构(ringbuf struct)分开声明的,并且管理结构中只定义了指向该数据的指针。“我认为这对我来说可以很好地工作。@Nick编写一个在模块中声明的
结构上运行的模块,这是获得像抽象和封装这样的面向对象的常见方法:)我在整个应用程序中都是这样做的。typedef struct serial_queue_t在我的uart模块中-我创建的所有实例都声明为静态的,因此它们被封装在uart模块中。我的实现与您链接的实现之间的唯一区别在于,在我的实现中,数据存储是在结构本身(字符数组x[])中定义的,因此,当声明该结构的实例时,也会声明存储(而不是指向外部存储的指针)。这就是我的方法限制我的原因!