有没有办法深入到 printf 的核心?我需要尽可能快的 USB 输出,但是
printf()
非常慢,所以我想摆脱函数内部发生的所有格式化。 printf 在哪里声明的?它很可能在标准输出库中,但是我在哪里可以找到它(我正在使用 Visual Studio 代码)。
背景(使用 SDK lib 在 Raspberry Pi Pico 上工作 - 但与此问题无关):
我想从 SPI1 读取 16 位十六进制值,并在中断中“实时”将它们写入 USB。所以我的程序有点像这样:
Do nothing until SPI Interrupt triggers
Read data from SPI1
Write data to COM19 on PC via USB
来自主机的 SPI 数据以 4MHz 的速率传入,数据字之间有约 480ns 的间隙。一个数据包大约需要 4.5us(从字 1 的位 1 到字 2 的位 1 测量)。意味着中断的最大时间不应大于4,5us。带有
printf()
的中断函数大约需要9us来处理,所以速度太慢并且有些数据没有被捕获。 Write()
能够在一个周期的时间内处理完毕,只需要大约2us。问题在于,数据在 COM 端口 (Putty) 上以 ASCII 形式打印。我禁用了很多 SDK 功能来优化运行时,我想知道我可以对 printf()
做同样的事情吗?必须可以直接写入 TX 寄存器并将其发送到 PC,但我在研究中找不到有关此主题的任何内容。
我需要加快
printf()
功能的速度,或者找到一些替代方案,因为它显然会减慢我的程序速度。
这速度怎么样..
char *hex = "0123456789ABCDEF";
char buf[4];
buf[3] = hex[n >> 0 & 0xF];
buf[2] = hex[n >> 4 & 0xF];
buf[1] = hex[n >> 8 & 0xF];
buf[0] = hex[n >>12 & 0xF];
write( fd, buf, sizeof buf );
需要考虑“字节顺序”,但无法想象你可以比这更快......
由于您尚未指定所有要求和环境条件,因此此列表仅收集想法。有些可能有效,有些则无效。这完全取决于您在问题中未提供的条件。如果某些术语对您来说是新的,请将它们用作研究的起点。
按照其他人的建议,使用一个或多个表从二进制转换为 ASCII。这只会加快转换速度。
不传输ASCII,发送二进制值。您可能使用的 ASCII 十六进制值至少需要 5 个字符,其中 4 个字符用于数字,1 个分隔符。与二进制相同的值只有 2 个字节。此外,您不需要任何转换。
将数据的获取与传输分离。例如,您可以使用足够大的循环缓冲区来处理平均吞吐量。请注意,您有多个线程,请仔细设计您的软件。
无论如何,请确保接收机器可以处理该数据速率。众所周知,PC 依赖于负载,甚至一次又一次地“睡眠”,因为它们的操作系统不是实时操作系统。