如何向PPC-Boot中添加自定义命令

http://blog.youkuaiyun.com/sailor_8318/article/details/4332088

【摘要】:本文介绍了PPC-Boot中命令的组织结构及解析过程,接着介绍了添加自定义命令的基本框架,为Pbist项目中如何添加自定义测试功能奠定了基础。PPC-Boot命令的检测及解析机制可在PUC Boot中借鉴,其可扩展行裁剪性非常适合用嵌入式系统应用。

【关键字】:PPC-Boot;MPC8270;run_command ; parse_line;find_cmd

 

1、命令结构定义

2、命令解析过程

3、如何添加用户命令

1)、定义CACHE命令标志位

2)、配置系统当前支持的CMD

3)、实现CACHE命令的操作函数

4)、添加命令表项宏定义

5)、添加命令到系统搜索列表中

6)、更改Makefile

 

 

PPC-Boot的命令为用户提供了交互功能,并且已经实现了几十个常用的命令。如果开发板需要很特殊的操作,可以添加新的PPC-Boot命令.


1、命令结构定义

PPC-Boot的每一个命令都是通过MK_CMD_TBL_ENTRY宏定义的。这个宏在include/command.h头文件中定义,每一个命令定义一个cmd_tbl_t结构体。

#ifdef    CFG_LONGHELP

#define  MK_CMD_TBL_ENTRY(name,lmin,maxargs,rep,cmd,usage,help)  /

                                                {name, lmin, maxargs, rep, cmd, usage, help }

#else     /* no helpinfo */

#define  MK_CMD_TBL_ENTRY(name,lmin,maxargs,rep,cmd,usage,help)  /

                                                {name, lmin, maxargs, rep, cmd, usage }

#endif

 

struct cmd_tbl_s {

            char                  *name;              /* Command Name                                 */

            int                    lmin;                 /* minimum abbreviated length    */

            int                    maxargs;           /* maximum number of arguments           */

            int                    repeatable;         /* autorepeat allowed?                */

                                                            /*Implementation function         */

            int                    (*cmd)(struct cmd_tbl_s *,int, int, char *[]);

            char                  *usage;              /* Usage message           (short)   */

#ifdef    CFG_LONGHELP

            char                  *help;               /* Help  message            (long)   */

#endif

};

 

这样每一个PPC-Boot命令有一个结构体来描述。结构体包含的成员变量:命令名称、最大参数个数、是否允许重复执行上一个命令、命令执行函数、用法、帮助。

Name是匹配因子,大小写必须一致,否则无法识别。

 

2、命令解析过程

从控制台输入的命令是由common/main.c中的程序解释执行的。

main_loop为循环入口函数,其在指定的延时时间内检测是否有输入,若没有,则自动运行“bootcmd”所指定的命令;若有输入,则readline循环检测用户输入,用户输入Enter后,run_command执行输入命令,其解析由“;”所分割的每个命令,parse_line将命令及其参数重新组织,find_cmd进行命令匹配检测,命令匹配成功后,将其传给命令表中注册的执行函数

(cmdtp->cmd) (cmdtp,flag, argc, argv)

由具体的命令函数进一步检查相关参数。

 

涉及的相关函数列表如下:

/* common/main.c */

int readline (const char *const prompt)

int run_command (const char *cmd, int flag)

int parse_line (char *line, char *argv[])

 

/* common/command.c */

cmd_tbl_t *find_cmd(const char *cmd);

find_cmd()负责匹配输入的命令,从列表中找出对应的命令结构体。

 

3、如何添加用户命令

由上面命令解析的过程可知,添加一个新命令,只需要实现命令对应的函数即可,命令的输入及解析无需我们关心。

 

基于PPC-Boot命令的基本框架,来分析一下简单的icache操作命令,就可以知道添加新命令的方法。

 

1)、定义CACHE命令标志位

在include/cmd_confdefs.h中定义了所有PPC-Boot命令的标志位。

#defineCFG_CMD_CACHE                   0x00000010       /* icache, dcache                        */

如果有更多的命令,也需要在这里添加定义,不能与其他命令的标志位冲突。

 

2)、配置系统当前支持的CMD

PPC-Boot的命令系统扩展性非常好,可以定制,添加删除,打开CONFIG_COMMANDS选项的命令标志位。这个程序文件开头 有#if语句需要预处理是否包含这个命令函数。CONFIG_COMMANDS选项在开发板的配置文件中定义当前支持的所有命令。例如:SMDK2410平台在 include/configs/smdk2410.h中有如下定义。

#define CONFIG_COMMANDS              (CONFIG_CMD_DFL| /

                                                 CFG_CMD_I2C            |/

                                                 CFG_CMD_CACHE     |/

                                                 CFG_CMD_MII   | /

                                                 CFG_CMD_EEPROM)

 

/* this must be included AFTER the definition ofCONFIG_COMMANDS (if any) */

#include <cmd_confdefs.h>

 

3)、实现CACHE命令的操作函数

下面是common/cmd_cache.c文件中icache命令部分的代码。

为了便于裁剪代码,程序都是通过1和2两步所定义的宏开关来控制的。

 

#if (CONFIG_COMMANDS &CFG_CMD_CACHE)

static int on_off (const char *s)

{       //这个函数解析参数,判断是打开cache,还是关闭cache

        if (strcmp(s,"on") == 0) {  //参数为“on”

               return(1);

        } else if(strcmp(s, "off") == 0) {  //参数为“off”

               return(0);

    }

    return (-1);

}

 

int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char*argv[])

{     //对指令cache的操作函数

      switch (argc) {

      case 2:               /* 参数个数为1,则执行打开或者关闭指令cache操作 */

             switch(on_off(argv[1])) {

             case0:     icache_disable();        //打开指令cache

                  break;

             case1:     icache_enable ();        //关闭指令cache

                  break;

             }

            /* FALLTROUGH */

      case 1:           /* 参数个数为0,则获取指令cache状态*/ 

            printf("Instruction Cache is %s/n",

                   icache_status() ? "ON" : "OFF");

            return 0;

     default:  //其他缺省情况下,打印命令使用说明

            printf ("Usage:/n%s/n",cmdtp->usage);

            return 1;

      }

      return 0;

}

 

4)、添加命令表项宏定义

一般在相应命令的头文件中定义该命令表项宏,如/include/cmd_cache.h

#if (CONFIG_COMMANDS &CFG_CMD_CACHE)

#define  CMD_TBL_ICACHE      MK_CMD_TBL_ENTRY(                                                           /

            "icache",           2,         2,         1,         do_icache,                                 /

            "icache  - enable or disable instructioncache/n",                            /

            "[on,off]/n"                                                                                          /

            "    - enable or disable instructioncache/n"                                                /

),

 

#define CMD_TBL_DCACHE     MK_CMD_TBL_ENTRY(                                                           /

            "dcache",           2,         2,         1,         do_dcache,                                /

            "dcache  - enable or disable data cache/n",                                                /

            "[on,off]/n"                                                                                          /

            "    - enable or disable data (writethrough)cache/n"                                   /

),

int do_icache (cmd_tbl_t *cmdtp, int flag, int argc, char*argv[]);

int do_dcache (cmd_tbl_t *cmdtp, int flag, int argc, char*argv[]);

#else

#define CMD_TBL_ICACHE

#define CMD_TBL_DCACHE

#endif   /*CFG_CMD_CACHE */


当系统不支持某命令时,该宏自动实现为空,对系统不会有任何影响,尤其是下面的命令数组,其不需要再用宏来控制

 

5)、添加命令到系统搜索列表中

/common/command.c中包括了系统所有的命令

首先添加上面某命令的头文件,如#include<cmd_cache.h>

 

然后添加命令到搜索列表中,否则系统无法识别该命令。注意此数组的排列顺序是按照字母顺序组成的,便于搜索,因此新添加的命令一定要遵循此规则。

/*

 * The commands inthis table are sorted alphabetically by the

 * command name and in descending order by thecommand name string

 * length. This is to prevent conflictsin command name parsing.

 * Please ensure thatnew commands are added according to that rule.

 * Please use$(TOPDIR)/doc/README.commands as a reference AND make

 * sure it getsupdated.

 */

 

cmd_tbl_t cmd_tbl[] = {

            CMD_TBL_ASKENV

            CMD_TBL_ASM

            CMD_TBL_AUTOSCRIPT

。。。。。

            CMD_TBL_BSP

。。

            CMD_TBL_DCACHE

。。

#if defined(CONFIG_PUC8250) || defined(CONFIG_PUC8260) ||defined(CONFIG_PUC8270)

#if defined(AXR)

            CMD_TBL_TEST_ALL_AXR

#elif defined(ODU_LC)

            CMD_TBL_TEST_ALL_MSH

#elif defined(XMP1)

            CMD_TBL_TEST_ALL_XMP1

#endif

            CMD_TBL_TEST_EEPROM

            CMD_TBL_TEST_ETHERNET

            CMD_TBL_TEST_FLASH

            CMD_TBL_TEST_RS232

            CMD_TBL_TEST_SDRAM

#if defined(L2C)

            CMD_TBL_INV_L2C

#endif

#endif

            CMD_TBL_QUES                     /* keep this("help") the last entry */

            /*the following entry terminates this table */

            MK_CMD_TBL_ENTRY(NULL, 0, 0, 0, NULL, NULL, NULL )

};

 

cmd_tbl数组的大小是由CONFIG_COMMANDS所定义支持的命令数来决定的,大小是动态的,因此需要一个表项来表示结束MK_CMD_TBL_ENTRY(NULL, 0, 0, 0, NULL, NULL, NULL )

 

裁剪CONFIG_COMMANDS时,无需再更改此数组,因为由第四步可知,相关表现自动为空。

 

6)、更改Makefile

在common/Makefile中添加编译的目标文件,否则系统不会编译新添加的代码。

COBJS  = main.oaltera.o bedbug.o /

              cmd_autoscript.o cmd_bedbug.o cmd_boot.o /

              cmd_bootm.o cmd_cache.ocmd_console.o cmd_date.o /

              cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o /

              cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_flash.o/

              cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o /

              cmd_jffs2.o cmd_mem.o cmd_mii.o cmd_misc.o /

              cmd_net.o cmd_nvedit.o env_common.o /

              env_flash.o env_eeprom.o env_nvram.oenv_nowhere.o /

              cmd_pci.o cmd_pcmcia.o cmd_test.o/

              cmd_reginfo.o cmd_scsi.o cmd_vfd.o cmd_usb.o/

              command.o console.o devices.o dlmalloc.o /

              docecc.o environment.o flash.o fpga.o /

              hush.o kgdb.o lists.o miiphybb.o miiphyutil.o/

              s_record.o soft_i2c.o soft_spi.o cmd_spi.ospartan2.o /

              usb.o usb_kbd.o usb_storage.o /

              virtex2.o xilinx.o


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值