前段时间我在SO上发布了this个问题。在那个问题中,我一直在寻找一种方法来实现我们想到的解决方案。但是根据我得到的答案,我看到使用默认的C预处理器无法实现该解决方案。
所以我决定直接发布问题并查看是否找到了合适的解决方案。
问题陈述
我们有一个自定义硬件平台,我们使用Contiki OS来构建固件。硬件基于MSP430微控制器。作为一个嵌入式和受限制的环境,我们正在寻找优化代码的方法。
我们想要优化的一个领域是我们正在打印到控制台的日志。由于原因,默认的printf()
功能无效。因此,我们有自己的功能,可以使用UART打印到控制台。
void ax_log_msg(enum log_msg_id,char * message);
这显然只会采用与printf()
不同的固定字符串,但它符合我们的目的。
现在我们在函数中提供的固定字符串显然会占用大量内存。我们希望通过在实际编译之前执行 something 来减少内存使用量,这将使用每个调用唯一的固定整数/数字替换字符串。它还将生成一个表或文件,其中整数将映射到它们替换的字符串。该表将在用户端应用程序中用于显示实际消息,而设备将只打印整数。
所以我正在寻找的是一种实现这种解决方案的方法。任何答案都会有所帮助:只是想法或预先存在的解决方案;什么都有帮助。
附加说明
log_msg_id
枚举和用户想要打印的消息彼此无关。枚举值主要用于对表/文档的字符串进行分组。
我们正在使用TI CCS IDE来构建我们的应用程序。
每个唯一字符串的唯一值而不是每次调用都会更好,但不是必需的。
固件以C语言编写。
将要打印的消息可以是用户/程序员想要的任何内容。系统应该从代码中挑选出来。
由于固件代码将跨越不同人编写的多个文件,因此系统应该能够保存文件中的值。这是未使用基本C预处理器的原因之一。
如果缺少任何信息,请提及,我会添加。
谢谢
答案 0 :(得分:3)
听起来像是X-macros的工作:
<强> log_table.x 强>
/*Symbol ID Message */
X(LOG_ID_BOOTING, 1, "Booting" )
X(LOG_ID_OUT_OF_MEM, 2, "Out of memory" )
X(LOG_ID_FOO_BAR, 3, "Foo failed to bar")
<强> log.h 强>
/* Generate list of available ID numbers */
enum LogID {
#define X(a, b, c) a = b,
#include "log_table.x"
#undef X
};
void do_log(enum LogID id);
<强> some_module.c 强>
p = malloc(sizeof(Foo));
if(!p)
do_log(LOG_ID_OUT_OF_MEM);
请注意,您可以在日志表中添加更多列,例如错误级别等。
在此示例中,我完全忽略了消息列。这是主要优势。您可以生成字符串表以调试版本,并将其从最终版本中删除。
另一个很好的优点是.x文件很容易解析,所以你可以使用Python脚本生成漂亮的PDF文件,其中包含所有错误代码和解释。