2
我有一个简单的命令行界面在我的AVR微控制器固件,根据各地的结构是这样的:CLI命令表GCC
typedef struct {
const char *name;
const char *usage;
const char *help;
void (*handler)(char **last);
} command_t;
extern command_t *cli_commands[];
我希望能在声明中不同模块的命令尽可能干。到目前为止,我有这样我定义我的功能是这样的:
COMMAND_IMPL(replay, "replay <n>", "Replay frame n") {
// 'last' argument is for strtok_t
}
,然后我必须有这个在我.c
文件之一:
COMMAND_DECL(list);
COMMAND_DECL(clear);
COMMAND_DECL(replay);
COMMAND_TABLE
COMMAND(list)
COMMAND(clear)
COMMAND(replay)
END_COMMAND_TABLE
我的宏是这样的:
#define COMMAND_IMPL(name, usage, help) \
static void cli_handle_##name##_command(char **);\
command_t cli_##name##_command = {#name, usage, help, cli_handle_##name##_command};\
static void cli_handle_##name##_command(char **last)
#define COMMAND_DECL(name) extern command_t cli_##name##_command;
#define COMMAND_TABLE command_t *cli_commands[] = {
#define COMMAND(name) ((command_t *) &cli_##name##_command),
#define END_COMMAND_TABLE NULL };
可以做得比这更好吗?这个项目已经与avr-gcc绑定了,所以我不介意它是否是GCC专用的解决方案。链接器功能的解决方案也可以(我正在编译为ELF)。我在想,也许我可以将命令条目放在不同的部分,并将其链接到已知的某个地方,但我不知道它会如何终止。
请注意,您不需要此链接器脚本。海湾合作委员会将使2个符号可用于您的部分。您可以简单地声明'extern command_t * __ start_commands;'和'extern command_t * __ stop_commands;'来获取指向创建的“commands”部分的开头和结尾的指针。 – nos
如何控制该部分进入哪个部分?我需要它进入文本段(我认为 - 这是AVR pgmspace数据)。 – Derecho
我从ld得到这个错误: /opt/local/lib/gcc/avr/4.7.2/../../../../avr/bin/ld:在[000000000000175a加载的部分cli_cmdtable, 0000000000001771] overlapped section .data loaded at [000000000000175a,000000000000193b] – Derecho