gpt4 book ai didi

c - 格式化打印到循环缓冲区

转载 作者:太空狗 更新时间:2023-10-29 15:06:01 25 4
gpt4 key购买 nike

我正在为 STM32F3 mc (STM32F3-Discovery) 编写嵌入式代码。我需要将一些数据输出到 UART,为此我使用 DMA,因为这让我可以专注于传感器读取和数据处理,而不是等待字节传输完成。然而,问题是我必须结合:

  1. 格式化输出(即来自 printf 的一些输出)
  2. 连续打印的次数(发生在上一次打印完成之前)

所以我在考虑循环缓冲区。但我不认为我知道如何让 sprintf 尊重缓冲区的结尾并继续写入缓冲区的开头。我当然可以创建另一个临时缓冲区,在那里打印,然后逐字节复制,但它对我来说看起来并不优雅。

最佳答案

一个解决方案可能是实现您自己的 sprintf,它能够与环形缓冲区一起工作。不幸的是,这不会帮助您解决一个更基本的问题:如果您的环形缓冲区已满并且您调用 sprintf,您会怎么做?

如果您的内存情况可以负担得起,我会建议针对此问题的另一种解决方案:

这个想法基于两个缓冲区链表(一个列表用于空闲缓冲区,一个列表作为传输队列)。缓冲区大小相等,因此它们可以存储最坏情况下长度的字符串。缓冲区构建一个简单的堆,其中分配/取消分配只是从空闲列表或传输列表中出列/入列元素。

具有相同大小的缓冲区可确保您在动态分配内存时不会受到外部碎片效应(如“棋盘格”)的影响。为此作业构建您自己的堆还可以让您完全控制可用于传输任务的总缓冲区大小。

我可以想象这个运行如下:

  1. 您从空闲列表中分配一个缓冲区来呈现数据。
  2. 使用您的渲染函数(例如 sprintf)渲染缓冲区中的数据
  3. 将要发送的数据追加到传输队列(必要时触发传输)

对于 DMA 传输,您处理传输结束 IRQ。在那里,您将刚刚传输的缓冲区移动到“空闲列表”,并为队列中的下一个缓冲区设置传输。

这个解决方案不会是内存效率最高的,但运行时效率很好,因为您只写入内存一次,分配/解除分配只是在某处获取/存储一个指针。当然,您必须确保您的应用程序和用于分配/解除分配的 IRQ 之间不会出现竞争条件。

也许这个想法给了你解决需求的灵感。

关于c - 格式化打印到循环缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14926294/

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