当前位置:首页 > 嵌入式 > 嵌入式硬件
[导读]收藏评论(0)分享到微博QQ微信LinkedIn命令行是计算机系统中最重要的组件之一。它可以帮助开发人员更方便的控制系统。在调试过程中,可以让开发人员随时变更测试方法。FPGA的

收藏

评论(0)

分享到

微博

QQ

微信

LinkedIn

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

FPGA的成本越来越低,FPGA上的嵌入式系统(SOPC)也应用得越来越广泛。但是相对其他成熟的计算机体系,SOPC系统现在还没有命令行。为了更好的推广SOPC应用,笔者开发了一个智能的命令行模块,可以调用系统中的任意函数,降低了开发人员的使用难度。在最小配置时,它只有大约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类型整数的参数,将真实的值传递给函数;对于其他参数,则将参数作为一个字符串传递给函数。

5 字符输入

命令行从标准输入设备中获取字符。命令行只接受可打印的字符和特定的控制字符。如果收到了回车或者换行字符,代表用户完成了命令输入,就解析命令。解析命令前,去掉多余的空格符(0x20),即不允许有连续的两个或多个空格符存在,命令的最后也不能有空格符。

6 参数解析

命令行模块要从用户输入的字符串中解析出命令名和参数。为命令提供与DOS和Linux类似的两个参数,argc和argv。argc表示参数的个数;argv是字符串指针的数组,最多10个字符串。argv[0]是第一个参数,argv[1]是第二个参数,如此类推。

7 函数解析

在代码中使用SHELL_CMD_DECL创建了命令列表,使用工具创建了自动命令列表。这两个表实际上都是数据结构ncommand_t的数组,其中有命令名和函数地址的信息。解析函数实际上就是根据在这两个数组中依次比较函数名。如果用户输入的命令名和数组中的命令名一致,就使用对应的函数地址。

8 命令执行

得到函数地址后,就可以执行命令对应的函数。对于主动创建的命令,使用argc和argv作为参数。对于自动命令,命令行模块先尝试将原始参数转换无符号整数。如果成功,使用无符号整数作为参数;如果不成功,则将原始参数的地址作为参数,实际上是一个字符串。

命令设计

完成总体设计后,就可以逐个添加开发需要的命令了。

● 帮助命令用于显示所有命令名及其用法。

● IO命令用来访问输入输出设备的寄存器,可以实现对外部设备的控制。

● 存储器命令用来显示、修改存储器的值。最基本的包括:dump命令显示指定位置的内存的值;modify命令用来修改指定内存单元的值。

● 用户在使用过程中,会使用很多命令。能够查询历史命令、循环执行历史命令将给用户带来很多方便。因此笔者实现了三条命令。history_show用来显示所有已经使用了的命令;history_del用来删除指定的历史命令;history_exec用来执行指定的历史命令。[!--empirenews.page--]

优化处理

Altera提供了简化版的输出函数alt_printf来替代printf,降低了嵌入式系统的开销,笔者在命令行中也支持这个这个函数。命令行的代码中,只调用SHELL_PRINT;在头文件中,根据用户设置,SHELL_PRINT使用标准的printf或者简化的alt_printf。如果使用简化的alt_printf,这个命令行占用的内存小于14KB。

在SOPC系统中的应用

Altera为SOPC系统开发提供的集成开发环境NIOS II IDE附带了多个软件实例。在使用这些软件实例时,用户只需要选择模块,完全不用新编代码,非常简单。

智能命令行模块也可以作为NIOS II IDE的一个实例。先在“nios2edsexamplessoftware”目录下为命令行创建一个子目录shell_standard,再以其他软件实例的template.xml为模板创为命令行建一个template.xml文件,然后复制命令行模块的所有文件到这个目录中。这样,用户在创建工程时,直接选中智能命令行模板,就可以使用智能命令行模块了。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式系统开发、调试和测试过程中,J-Link作为一种高效的调试工具,为开发者提供了极大的便利。然而,要想充分发挥J-Link的功能,首先需要正确安装其驱动程序。本文将详细介绍J-Link驱动的安装过程,并深入解析其中...

关键字: jlink 嵌入式系统 嵌入式开发

与谷歌的合作使 Nordic 能够在 nRF Connect SDK 中嵌入开发人员软件,以构建与安卓移动设备兼容的谷歌Find My Device和未知跟踪器警报服务

关键字: 谷歌 SoC 嵌入式开发

嵌入式开发作为当今电子工程和信息技术领域的核心分支,涵盖了广泛的软硬件技术和系统集成方法,用于构建高性能、低成本、低功耗、体积小巧且功能专一的嵌入式系统。这些系统无处不在,从微型传感器节点到复杂的工业控制设备,从日常使用...

关键字: 嵌入式开发 Python

嵌入式开发是当今信息技术领域不可或缺的一部分,它融合了硬件设计、软件开发和系统集成等多个学科,专门用于创建那些被嵌入到特定设备或系统中的专用计算机系统。嵌入式开发的主要过程包括利用分立元件或集成器件进行电路设计、结构设计...

关键字: 嵌入式开发 硬件设计 软件开发

嵌入式开发作为一种专业且技术密集型的领域,涵盖了从硬件底层驱动、中间件到应用层软件开发等多个层面的工作,其所需的工具种类繁多,各有针对性,旨在提升开发效率、保证代码质量以及简化调试过程。

关键字: 嵌入式开发 keil

嵌入式开发作为信息技术领域的重要分支,其涉及的语言种类繁多,各具特色。这些语言的选择取决于目标平台的特性、性能需求、开发者的熟练程度以及项目的具体要求。本文将详细介绍几种常见的嵌入式开发语言,包括C语言、C++、汇编语言...

关键字: 嵌入式开发 C语言

嵌入式开发是一项综合了硬件设计、软件编程以及系统整合的技术活动,其目的是为了创造出能够在特定环境中高效、稳定运行的嵌入式系统。这一流程涵盖了多个紧密关联且不可或缺的阶段,从最初的客户需求分析到最终的产品测试和交付,每个环...

关键字: 嵌入式开发 硬件设计

嵌入式开发作为一个融合了计算机软硬件和系统工程的综合性领域,其成功与否往往取决于三个核心要素的有效整合与协调。这三个要素分别是:硬件平台的选择与设计、软件开发及其优化、以及系统级的设计与集成。深入理解并熟练掌握这三个方面...

关键字: 嵌入式开发 ARM

嵌入式开发作为信息技术的关键支柱,在全球数字化转型浪潮中扮演着无可替代的角色。从传统的嵌入式微控制器到如今先进的片上系统(SoC),再到与云计算、人工智能深度融合的智能终端,嵌入式系统的演进与发展始终紧跟时代脉搏。本文将...

关键字: 嵌入式开发 智能应用

嵌入式开发是一种专门针对特定硬件平台设计和实现软件系统的工程实践,它涵盖了从需求分析、系统设计、编程实现、调试测试直到产品部署及维护的全过程。本文将深入探讨嵌入式开发的主要阶段,分解其流程并阐述每个步骤的关键要点,以便于...

关键字: 嵌入式开发 嵌入式软件
关闭
关闭