2

我知道 printf 和 sprintf 之间的基本功能差异。但是,我想知道它们之间的一些与时间/延迟相关的差异。显然,我想在我的任务中使用它来定制构建的 RTOS。你怎么看 ?我想知道更多它将如何影响系统的性能。(如果有的话)。通常,由于大量延迟,我不使用打印功能,但是我必须在这里强制使用它。

仅供参考,输出使用 RS232 显示在终端窗口上。

谢谢。

4

3 回答 3

6

这里的主要问题是printf()写入stdout可以(并且几乎肯定会)阻塞调用线程。在嵌入式系统中stdout,速度非常慢的 RS232 端口并不少见。

出于这个原因,您永远不会在实时线程中执行此操作,因为它会迅速变得非实时。

写入缓冲区sprintf()相当便宜(假设缓冲区已被分配)。它当然不会阻塞。

您可能会发现您的 RTOS 提供了一种异步日志记录机制,该机制可以从实时线程中调用而没有阻塞的风险。这只不过是一个环形缓冲区,您可以将终端输出写入其中,并使用较低优先级的线程将其打印到终端。

于 2012-09-28T10:49:56.990 回答
2

嗯......所有其他事情(未指定)都是平等的,我想sprintf()应该比 '快' printf(),因为前者只是写入内存缓冲区,而后者写入一些 I/O“设备”。大多数设备会产生比写入 RAM 更多的延迟,这就是为什么printf()可能会更慢。

尽管这些差异可能很小,但主要问题是大多数实现都进行动态内存分配,这可能非常昂贵。

我建议您减少您的需求,以便您可以在 使用现成sprintf()实现的情况下实现它们,或者通过您必须查看它们是否/何时进行堆分配的实现代码。

于 2012-09-28T09:23:24.230 回答
2

sprintf() 没有硬件依赖, printf() 受制于您对标准输出的底层低级支持。正如您所说,将数据推送到 UART 并忙于等待发送寄存器或 FIFO 可用的幼稚实现确实会产生“巨大延迟”——但这在实时系统中将是一种愚蠢的实现。

您通常会将数据推送到由中断例程提供服务的环形缓冲区、管道或字符队列。如果当您将数据推送到缓冲区时缓冲区为空,您将强制发送器通过缓冲除第一个字符之外的所有字符开始,然后将其直接写入 UART。然后,UART 中断将使发送器保持馈送,直到缓冲区为空。从您的应用程序级别来看,您只是将数据写入内存,因此延迟将是最小且确定性的。

stdin 可以类似地实现,ISR 写入和应用程序异步读取。

通过使用诸如管道或队列之类的 RTOS IPC 机制,或使用诸如信号量之类的同步原语,您可以在数据输出上实现阻塞、阻止和超时语义。

If your UART supports DMA, you can potentially further reduce the interrupt rate and CPU overhead.

于 2012-09-28T20:29:51.607 回答