1. 具體實現步驟
① 在./common文件夾下新建cmd_led.c,並在此文件中添加如下內容
#include <common.h> #include <command.h> int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { printf("Led test start\n"); return 0; } U_BOOT_CMD( led, 2, 0, do_led, "led test command", "led test command" );
② 在./common/Makefile中添加:
COBJS-y += cmd_led.o
③ 在Linux環境下,重新編譯u-boot,得到u-boot.bin,並下載到自己的開發板中測試,輸入help就會發現led命令
2.原理分析
① U_BOOT_CMD定義在include/command.h:
#define U_BOOT_CMD(name, maxargs, rep, cmd, usage, help) \ cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
② Struct_Section 定義為:
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
③ 我們定義的led命令結構展開為:
cmd_tbl_t __u_boot_cmd_led __attribute__ ((unused, section (".u_boot_cmd")))= {"led", 2, 0, do_led, "Led Usage", "Led Help"};
很明顯,這是在定義一個cmd_tbl_t類型的變量__u_boot_cmd_led,並給他賦初值。
__attribute__((unused, section(".u_boot_cmd")))該部分是對變量的特殊聲明(GNU特有),告訴編譯器,該變量存放在鏈接腳本所指定的u_boot_cmd段。
__u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .;
④ led命令執行過程:
在串口終端輸入"led"命令時,串口接收到數據,並傳遞給run_command()函數,run_command()函數調用common/command.c中實現的find_cmd()函數在u_boot_list段內查找命令,並返回cmd_tbl_t結構。然后run_command()函數使用返回的cmd_tbl_t結構中的函數指針調用do_led(),從而完成命令的執行。