我正在开发一个紧凑型的调试输出/单元测试工具,用于嵌入式系统。
我创建了一个系统,可以以紧凑的方式通过串口将消息输出到PC。为了节省内存空间/串口带宽,我通过给它们分配唯一的16位ID从嵌入式系统中剥离了消息字符串。
这很容易实现,因为我将所有消息都放在一个列表中。一些宏会将其转换成枚举:
projectdefs.h:
#define MESSAGE_TABLE(MSG) \
MSG(HELLO, "Hello World!") \
MSG(TEST, "Second message #ID 1") \
MSG(TEST2, "Third message #ID 2")
messages.h:
#define MACRO_STR_CONCAT(a,b) a##b
#define MESSAGE_ENUM(codeName, str) MACRO_STR_CONCAT(MSG_, codeName)
typedef enum messageNumbers_e {
MESSAGE_TABLE(MESSAGE_ENUM),
MESSAGE_COUNT
};
#define MESSAGE(codeName) messageSend(MACRO_STR_CONCAT(MSG_, codeName), __LINE__, file_number);
串行端口传输的唯一数据是消息ID、行号和文件号(注意:不是字符串!)。
我的问题在于,如何使用C预处理器/编译器为每个文件分配唯一的ID。我不想在嵌入式程序中存储每个文件名字符串。这会占用过多的内存或者串行端口带宽。
我的想法是,在每个源文件顶部使用宏定义来定义常数file_number。我将使用以下定义:
#define ASSIGN_FILENUMBER() enum { file_number = __COUNTER__ };
然而,由于每个文件都是单独编译的,这意味着
__COUNTER__
语句被调用时始终从0开始,并不知道其他文件或自己的ID。另一个考虑因素是编辑MakeFile(脚本)并在其中添加文件ID号码。然而,这将使项目构建/功能与我的IDE配置紧密耦合,这是不可取的。此外,我对当前IDE(XC16/XC32编译器,Mplab X IDE或IAR嵌入式工作台)的可能性不确定。
我想知道是否有其他创造性的方法可以让标准的C预处理器接管任务?
__COUNTER__
值,至少在MSVC文档中是这样写的。 - Alex FASSIGN_FILENUMBER
宏的头文件。我的编译器可能是基于gcc的,但并不太确定。 我可以看到预编译的头文件已被拾取(-H输出),但是处理器特定的定义无法编译:invalid attribute space, __sfr__, __unsafe__
等被忽略。 由于使用C语言编写的嵌入式软件是完全静态的程序,因此在设备内部动态分配/计算ID没有意义。此外,这将更难以跟踪主机。 - Hans