新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 智能命令行设计及其在SOPC系统中的应用

智能命令行设计及其在SOPC系统中的应用

作者:时间:2011-04-06来源:网络收藏

行是计算机中最重要的组件之一。它可以帮助开发人员更方便的控制。在调试过程中,可以让开发人员随时变更测试方法。

本文引用地址:http://www.eepw.com.cn/article/150890.htm


FPGA的成本越来越低,FPGA上的嵌入式)也得越来越广泛。但是相对其他成熟的计算机体系,系统现在还没有行。为了更好的推广,笔者开发了一个行模块,可以调用系统中的任意函数,降低了开发人员的使用难度。在最小配置时,它只有大约1000行代码,占用14KB存储容量,可以放在完全由FPGA片内资源构成的计算机系统中。它的结构也具有很好的扩展性,开发人员可以结合自己的需求,轻松添加命令,丰富它的特性。

命令行框架
1 总体
好的命令行要具有扩展性,开发人员能轻松添加自己的命令;也要傻瓜化,简单易于使用。


为了达到这两个目的,可采用编译器创建的数组作为命令的总索引数据结构。为每条命令创建一个变量,指定它放在一个命令行专用的段中;其中用段“shell_cmd_tab”存放用户主动创建的命令;用段“shell_cmd_tab_auto”存放系统中所有全局函数。创建变量只需调用宏SHELL_CMD_DECL,提供命令名、命令说明和函数名即可。这样就可以实现C语言函数、变量、段、内存区域的自动映射过程。


命令的数据结构如下。


typedef struct _ncommand_t {
const char *name;
const char *descr;
shell_st_call cfunc;
} ncommand_t;


为了简化命令的创建,定义下面这个宏来创建命令。
#define SHELL_CMD_DECL(name, usage, func) ncommand_t _shell_cmd_tab_##func _attribute_ ( (section( “.shell_cmd_tab”) ) )={ name, usage, func }; // small memory version
创建命令的实例如下:SHELL_CMD_DECL(“dump”, “Shows a memory dump”, hexdump);


2 连接脚本
在连接脚本里指定段的位置是简化命令行使用流程的关键。GCC使用PROVIDE定义变量。笔者使用PROVIDE定义了各个段的起始地址和结束地址,从而可以在代码中使用段地址查询到所有命令。在编译器使用的连接脚本中添加如下行定义函数表。


.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 动态函数表创建
由工具自动根据系统中的全局函数创建的命令被称为自动命令。自动命令使用户可以在命令行中调用任意普通函数,即使开发人员没有声明这些函数为命令。自动命令也需要一个数组包含系统中所有全局函数的信息,这个表为动态函数表。使用一个脚本根据系统的可执行文件自动生成动态函数表。要先编译软件,生成可执行文件;再调用脚本创建动态函数表;最后再编译出包含动态函数表的可执行文件。


在脚本中先使用GNU的nm工具从可执行文件导出所有全局符号,再使用grep提取出包括函数名的行,接着使用cut删除函数名前的地址信息,使用sed将字符T替换为创建命令的宏SHELL_CMD_DECL_AUTO,并在行尾添加括号。最后将所有这些信息写入一个C源代码文件,交给编译器编译,就能得到一个动态函数表。


4 自动命令参数个数
为了便于开发人员使用,自动命令最好能适应所有函数类型,假设都是unsigned int的函数类型。对于可以成功转化为unsigned int类型整数的参数,将真实的值传递给函数;对于其他参数,则将参数作为一个字符串传递给函数。


上一页 1 2 下一页

评论


相关推荐

技术专区

关闭