uboot 添加命令

1、 u-boot的命令格式:

U_BOOT_CMD(name,maxargs,repeatable,command,”usage”,"help")

name:命令的名字,不是一个字符串;

maxargs:最大的参数个数;

repeatable:命令是可重复的;

command:对应的函数指针

U-Boot的每一个命令都是通过U_Boot_CMD宏定义的。这个宏在头文件中定义
#ifdef  CFG_LONGHELP
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
#else    /* no long help info */
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
#endif    /* CFG_LONGHELP */
    每一个命令定义一个cmd_tbl_t结构体,而cmd_tbl_t只不过是cmd_tbl_s的一个typedef,如下所示:
                typedef struct cmd_tbl_s    cmd_tbl_t;

从控制台输入的命令是由common/command.c中的程序解释执行的。find_cmd()负责匹配输入的命令,从列表中找出对应的命令结构体。

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

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

 

#define CFG_CMD_CACHE       0x00000010ULL   /* icache, dcache       */

 

如果有更多的命令,也要在这里添加定义。

2)实现CACHE命令的操作函数。下面是common/cmd_cache.c文件中icache命令部分的代码。

 

#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;

}

……

U_Boot_CMD( //通过宏定义命令

    icache,   2,   1,     do_icache,  //命令为icache,命令执行函数为do_icache()

    "icache  - enable or disable instruction cache\n",   //帮助信息

    "[on, off]\n"

    "    - enable or disable instruction cache\n"

);

……

#endif

 

U-Boot的命令都是通过结构体__U_Boot_cmd_##name来描述的。根据U_Boot_CMDinclude/command.h中的两行定义可以明白。

 

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

 

还有,不要忘了在common/Makefile中添加编译的目标文件。

3)打开CONFIG_COMMANDS选项的命令标志位。这个程序文件开头有#if语句需要预处理是否包含这个命令函数。CONFIG_COMMANDS选项在开发板的配置文件中定义。例如:SMDK2410平台在include/configs/smdk2410.h中有如下定义。

 

/***********************************************************

 * Command definition

 ***********************************************************/

#define CONFIG_COMMANDS \

                 (CONFIG_CMD_DFL  | \

                 CFG_CMD_CACHE     | \

                 CFG_CMD_REGINFO    | \

                 CFG_CMD_DATE      | \

                 CFG_CMD_ELF)

 

按照这3步,就可以添加新的U-Boot命令。

下面以添加 "Hello Word!" 命令为例!

(1)
在include/configs/qljt2440.h中增加一项:

#define CONFIG_CMD_ASKENV
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
#define CONFIG_CMD_PING
#define CONFIG_CMD_NAND    //ql18
#define CONFIG_CMD_REGINFO   //ql18
#define  CONFIG_CMD_HELLOWORD

(2)
在 /board/qljt/qljt2440/ 目录下添加 helloword.c 文件
内容如下

/*
*!ql add for test add u-boot command
*/
#include
#include

#ifdef CONFIG_CMD_HELLOWORD
void helloword(void)
{
 qljt_printf("-----------------------------------------------Hello Word!\n");
}
U_BOOT_CMD(
 hello,
 1,
 2,
       helloword,
       "hell  - helloword command ",
       " QL add u-boot command!\n"
);

#endif
(3) 在/board/qljt/qljt2440/ 目录下的Makefile 添加要编译的目标文件,即在 Makefile的变量COBJS中加入:cmd_test_zwx.o

重新编译u-boot,完毕!

修改网卡控制字在文件dm9000x.c里,发送自定义包可以在/common/cmd_net.c文件里添加命令。

零值广播

static void start_ip_zerobro (void)
{
    int i = 0;
    uchar udp[14+20+8+306] = {
        0x23,0x45,0x3f,0x56,0xe3,0x2d,
        0x32,0x34,0xde,0x2d,0x4c,0x27,
        0x08,0x00,

        /* IP Header */
        0x45,0x00,0x01,0x4e,
        0xc1,0x3e,0x00,0x00,
        0x40,0x11,0xf6,0x36,
        0xc0,0xa8,0x01,0x82,
        0x00,0x00,0x00,0x00,

        /* UDP Header */
        0x0f,0x10,0x00,0x50,
        0x01,0x3a,0x2d,0x3b

        /* DATA 306B*/
    };

    while (i++<10)
    {
        eth_send((volatile void*)udp,sizeof(udp));
        printf("send ip zerobro package ok\n");
        sleep("1");
    }
}

static int sleep (char *string)
{
    ulong start = get_timer(0);
    ulong delay;

    delay = simple_strtoul(string, NULL, 10) * CONFIG_SYS_HZ;

    while (get_timer(start) < delay) {
        if (ctrlc ()) {
            return (-1);
        }
        udelay (100);
    }
    return 0;
}


 

原文地址:https://www.cnblogs.com/lovemo1314/p/2132382.html