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

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

Sailor_forever sailing_9806@163.com 转载请注明

http://blog.csdn.net/sailor_8318/archive/2009/07/08/4332088.aspx

 

 

**********************************************************************

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

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

 

1、命令结构定义 - 1 -

2、命令解析过程 - 1 -

3、如何添加用户命令 - 2 -

1)、定义 CACHE命令标志位 - 2 -

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

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

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

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

6)、更改 Makefile - 5 -

 

 

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 help info */

#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命令的标志位。

#define CFG_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 of CONFIG_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])) {

             case 0:     icache_disable();        //打开指令 cache

                   break;

             case 1:     icache_enable ();        //关闭指令 cache

                   break;

              }

            /* FALL TROUGH */

      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 instruction cache/n",                            /

            "[on, off]/n"                                                                                          /

            "    - enable or disable instruction cache/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 in this table are sorted alphabetically by the

  * command name and in descending order by the command name string

  * length. This is to prevent conflicts in command name parsing.

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

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

  * sure it gets updated.

  */

 

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.o altera.o bedbug.o /

              cmd_autoscript.o cmd_bedbug.o cmd_boot.o /

              cmd_bootm.o cmd_cache.o cmd_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.o env_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.o spartan2.o /

              usb.o usb_kbd.o usb_storage.o /

              virtex2.o xilinx.o

 

 

 

 


- 7 -

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值