一种解决方案可能是实现您自己sprintf
的能够与环形缓冲区一起使用的解决方案。不幸的是,这不会帮助您解决更基本的问题:如果您的 ringbuffer 已满并且您调用 ,您会怎么做sprintf
?
如果您的记忆力负担得起,我会建议这个问题的另一种解决方案:
这个想法基于两个链接的缓冲区列表(一个列表用于空闲缓冲区,一个列表作为传输队列)。缓冲区的大小相同,因此它们可以存储最坏情况长度的字符串。缓冲区构建一个简单的堆,其中分配/解除分配只是从空闲列表或传输列表中使元素出队/入队。
具有相同大小的缓冲区可确保您在动态分配内存时不会受到外部碎片影响,例如“棋盘式”。为这项工作构建自己的堆还可以让您完全控制可用于传输任务的总缓冲区大小。
我可以想象这个运行如下:
- 您从空闲列表中分配一个缓冲区以将数据呈现到其中。
- 使用您的渲染函数(例如 sprintf)渲染缓冲区中的数据
- 将要发送的数据附加到传输队列(必要时触发传输)
对于 DMA 传输,您处理传输结束 IRQ。在那里,您将刚刚传输的缓冲区移动到“空闲列表”并为队列中的下一个缓冲区设置传输。
此解决方案不会是内存效率最高的,但运行时效率很好,因为您只写入一次内存并且分配/释放只是在某处获取/存储指针。当然,您必须确保您的应用程序和分配/解除分配的 IRQ 之间没有竞争条件。
也许这个想法会给你一个灵感来解决你的需求。