智能命令行設計及其在SOPC系統中的應用
命令行是計算機系統中最重要的組件之一。它可以幫助開(kāi)發(fā)人員更方便的控制系統。在調試過(guò)程中,可以讓開(kāi)發(fā)人員隨時(shí)變更測試方法。
本文引用地址:http://dyxdggzs.com/article/150890.htm
FPGA的成本越來(lái)越低,FPGA上的嵌入式系統(SOPC)也應用得越來(lái)越廣泛。但是相對其他成熟的計算機體系,SOPC系統現在還沒(méi)有命令行。為了更好的推廣SOPC應用,筆者開(kāi)發(fā)了一個(gè)智能的命令行模塊,可以調用系統中的任意函數,降低了開(kāi)發(fā)人員的使用難度。在最小配置時(shí),它只有大約1000行代碼,占用14KB存儲容量,可以放在完全由FPGA片內資源構成的計算機系統中。它的結構也具有很好的擴展性,開(kāi)發(fā)人員可以結合自己的需求,輕松添加命令,豐富它的特性。
命令行框架設計
1 總體設計
好的命令行要具有擴展性,開(kāi)發(fā)人員能輕松添加自己的命令;也要傻瓜化,簡(jiǎn)單易于使用。
為了達到這兩個(gè)目的,可采用編譯器創(chuàng )建的數組作為命令的總索引數據結構。為每條命令創(chuàng )建一個(gè)變量,指定它放在一個(gè)命令行專(zhuān)用的段中;其中用段“shell_cmd_tab”存放用戶(hù)主動(dòng)創(chuàng )建的命令;用段“shell_cmd_tab_auto”存放系統中所有全局函數。創(chuàng )建變量只需調用宏SHELL_CMD_DECL,提供命令名、命令說(shuō)明和函數名即可。這樣就可以實(shí)現C語(yǔ)言函數、變量、段、內存區域的自動(dòng)映射過(guò)程。
命令的數據結構如下。
typedef struct _ncommand_t {
const char *name;
const char *descr;
shell_st_call cfunc;
} ncommand_t;
為了簡(jiǎn)化命令的創(chuàng )建,定義下面這個(gè)宏來(lái)創(chuàng )建命令。
#define SHELL_CMD_DECL(name, usage, func) ncommand_t _shell_cmd_tab_##func _attribute_ ( (section( “.shell_cmd_tab”) ) )={ name, usage, func }; // small memory version
創(chuàng )建命令的實(shí)例如下:SHELL_CMD_DECL(“dump”, “Shows a memory dump”, hexdump);
2 連接腳本
在連接腳本里指定段的位置是簡(jiǎn)化命令行使用流程的關(guān)鍵。GCC使用PROVIDE定義變量。筆者使用PROVIDE定義了各個(gè)段的起始地址和結束地址,從而可以在代碼中使用段地址查詢(xún)到所有命令。在編譯器使用的連接腳本中添加如下行定義函數表。
.shell :
{
PROVIDE (__ram_shell_start = ABSOLUTE(.));
. = ALIGN(32 / 8);
PROVIDE (__ram_shell_cmd_tab_begin = ABSOLUTE(.));
*(.shell_cmd_tab .shell_cmd_tab.*)
PROVIDE (__ram_shell_cmd_tab_end = ABSOLUTE(.));
PROVIDE (__ram_shell_cmd_tab_auto_begin = ABSOLUTE(.));
*(.shell_cmd_tab_auto .shell_cmd_tab_auto.*)
PROVIDE (__ram_shell_cmd_tab_auto_end = ABSOLUTE(.));
*(.shell .shell.*)
. = ALIGN(32 / 8);
PROVIDE (__ram_shell_end = ABSOLUTE(.));
} > ddr_sdram
3 動(dòng)態(tài)函數表創(chuàng )建
由工具自動(dòng)根據系統中的全局函數創(chuàng )建的命令被稱(chēng)為自動(dòng)命令。自動(dòng)命令使用戶(hù)可以在命令行中調用任意普通函數,即使開(kāi)發(fā)人員沒(méi)有聲明這些函數為命令。自動(dòng)命令也需要一個(gè)數組包含系統中所有全局函數的信息,這個(gè)表為動(dòng)態(tài)函數表。使用一個(gè)腳本根據系統的可執行文件自動(dòng)生成動(dòng)態(tài)函數表。要先編譯軟件,生成可執行文件;再調用腳本創(chuàng )建動(dòng)態(tài)函數表;最后再編譯出包含動(dòng)態(tài)函數表的可執行文件。
在腳本中先使用GNU的nm工具從可執行文件導出所有全局符號,再使用grep提取出包括函數名的行,接著(zhù)使用cut刪除函數名前的地址信息,使用sed將字符T替換為創(chuàng )建命令的宏SHELL_CMD_DECL_AUTO,并在行尾添加括號。最后將所有這些信息寫(xiě)入一個(gè)C源代碼文件,交給編譯器編譯,就能得到一個(gè)動(dòng)態(tài)函數表。
4 自動(dòng)命令參數個(gè)數
為了便于開(kāi)發(fā)人員使用,自動(dòng)命令最好能適應所有函數類(lèi)型,假設都是unsigned int的函數類(lèi)型。對于可以成功轉化為unsigned int類(lèi)型整數的參數,將真實(shí)的值傳遞給函數;對于其他參數,則將參數作為一個(gè)字符串傳遞給函數。
評論