我知道 printf 和 sprintf 之间的基本功能差异。但是,我想知道它们之间的一些与时间/延迟相关的差异。显然,我想在我的任务中使用它来定制构建的 RTOS。你怎么看 ?我想知道更多它将如何影响系统的性能。(如果有的话)。通常,由于大量延迟,我不使用打印功能,但是我必须在这里强制使用它。
仅供参考,输出使用 RS232 显示在终端窗口上。
谢谢。
我知道 printf 和 sprintf 之间的基本功能差异。但是,我想知道它们之间的一些与时间/延迟相关的差异。显然,我想在我的任务中使用它来定制构建的 RTOS。你怎么看 ?我想知道更多它将如何影响系统的性能。(如果有的话)。通常,由于大量延迟,我不使用打印功能,但是我必须在这里强制使用它。
仅供参考,输出使用 RS232 显示在终端窗口上。
谢谢。
这里的主要问题是printf()
写入stdout
可以(并且几乎肯定会)阻塞调用线程。在嵌入式系统中stdout
,速度非常慢的 RS232 端口并不少见。
出于这个原因,您永远不会在实时线程中执行此操作,因为它会迅速变得非实时。
写入缓冲区sprintf()
相当便宜(假设缓冲区已被分配)。它当然不会阻塞。
您可能会发现您的 RTOS 提供了一种异步日志记录机制,该机制可以从实时线程中调用而没有阻塞的风险。这只不过是一个环形缓冲区,您可以将终端输出写入其中,并使用较低优先级的线程将其打印到终端。
嗯......所有其他事情(未指定)都是平等的,我想sprintf()
应该比 '快' printf()
,因为前者只是写入内存缓冲区,而后者写入一些 I/O“设备”。大多数设备会产生比写入 RAM 更多的延迟,这就是为什么printf()
可能会更慢。
尽管这些差异可能很小,但主要问题是大多数实现都进行动态内存分配,这可能非常昂贵。
我建议您减少您的需求,以便您可以在不 使用现成sprintf()
实现的情况下实现它们,或者通过您必须查看它们是否/何时进行堆分配的实现代码。
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.