我知道printf和sprintf之间的基本功能差异。但是,我想知道它们之间的一些时间/延迟相关的差异。显然,我想在一个自定义构建的RTOS的任务中使用它。你怎么看 ?我想知道它将如何影响系统的性能。 (如果有的话)。通常,我不会因为大量的延迟而使用打印功能,但是我必须在这里强行使用它。
仅供参考,使用RS232在终端窗口上显示输出。
感谢。
答案 0 :(得分:6)
这里的主要问题是printf()
写入stdout
,它可以(并且几乎肯定会)阻止调用线程。在嵌入式系统上,stdout
成为一个非常慢的RS232端口并不罕见。
出于这个原因,你永远不会在实时线程中这样做,因为它很快变得很高,非实时。
使用sprintf()
写入缓冲区相当便宜(提供缓冲区已经分配)。它当然不会阻止。
您可能会发现您的RTOS提供了一种异步日志记录机制,可以从实时线程调用而不会有阻塞的风险。这只是一个环形缓冲区,您可以在其中编写终端输出,并使用较低优先级的线程将其打印到终端。
答案 1 :(得分:2)
嗯......所有其他事情(未指明)相等,我猜sprintf()
应该比printf()
“更快”,因为前者只是写入内存缓冲区,而后者写入一些I / O“设备”。大多数设备会产生比仅写入RAM更多的延迟,这就是printf()
可能更慢的原因。
这些差异可能很小,但主要问题是大多数实现都会进行动态内存分配,这可能非常昂贵。
我建议您删除您的要求,以便您可以使用现成的sprintf()
实现实现,或者通过您必须查看的实现代码if / when什么时候进行堆分配。
答案 2 :(得分:2)
sprintf()没有硬件依赖性,printf()受stdout底层的低级支持。将数据推送到UART并忙于等待发送寄存器或FIFO变为可用的简单实现确实会产生“大量延迟” - 但是这样做是一个愚蠢的实现。实时系统。
您通常会将数据推送到环形缓冲区,管道或字符队列,该队列由中断例程提供服务。如果当您要将数据推送到缓冲区时缓冲区为空,则会强制发送器通过缓冲除第一个字符之外的所有字符然后将其直接写入UART来启动。然后,UART中断将保持发送器馈电,直到缓冲器为空。从您的应用程序级别来看,您只是将数据写入内存,因此延迟将是最小的和确定性的。
stdin可以类似地实现,ISR写入和应用程序异步读取。
通过使用RTOS IPC机制(如管道或队列)或使用信号量等同步原语,您可以在数据输出上实现阻塞,阻塞和超时语义。
如果您的UART支持DMA,则可以进一步降低中断率和CPU开销。