zoukankan      html  css  js  c++  java
  • 在U-Boot中添加自定义命令以实现自动下载程序【转】

    本文转载自:https://gaomf.cn/2016/06/26/%E5%9C%A8U-Boot%E4%B8%AD%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%91%BD%E4%BB%A4%E4%BB%A5%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E4%B8%8B%E8%BD%BD%E7%A8%8B%E5%BA%8F/

    U-Boot中通过NFS下载程序是一种很普遍的方式,然而下载程序的过程并不能只用一条命令实现。以下载到NOR Flash中为例,一般需要以下几步:

    1. 通过NFS将文件下载到内存中;
    2. 解除NOR Flash写保护;
    3. 擦除NOR Flash;
    4. 写入NOR Flash。

    每一步都需要手动输入命令,十分麻烦,所以我们可以在U-Boot中添加一个自定义命令download,以实现一键全自动下载的目的。下面就来介绍一下实现方法。

    向U-Boot中添加命令

    以U-Boot 2016.05为例,其绝大部分命令都位于cmd/文件夹中,可以选择一个简单点的文件打开看看,就可以看到命令接口的基本结构如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static int do_mycmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    {
    // Do Something
    }

    U_BOOT_CMD(
    mycmd, 1, 1, do_mycmd,
    "short description",
    "help"
    );

    其中do_mycmd()函数就是命令的执行函数,它的名字可以是任意的,只是按照U-Boot惯例一般就叫做这种形式。此函数的cmdfpflag两个参数是由U-Boot系统传入的和命令相关的一些信息,一般用不到,重点是后两个参数。argc是参数个数,至少为1,表示命令本身;argv就是具体传入的参数字符串数组。

    这个一般的函数是如何和命令关联起来的呢?靠的就是U_BOOT_CMD这个宏。这里不详细分析此宏的实现机理,仅从应用的角度说明一下。U_BOOT_CMD的命令格式为:

    1
    U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)

    各参数的含义为:

    参数含义
    name 命令的名称,此处直接输入即可,不要用字符串"xxx"的形式
    maxargs 命令的最大参数个数,至少为1,表示命令本身
    rep 是否自动重复(为1的话下次直接按Enter键会重复执行此命令)
    cmd 命令对应的响应函数,即之前的do_mycmd()函数,直接使用函数名
    usage 简短的使用说明(字符串)
    help 输入help后显示的较详细的帮助文档(字符串)

    按以上格式新建一个C源文件后,将其加入Makefile中编译即可。这个文件可以放在任何地方,不过cmd/文件夹中存放的是通用的命令,我们自己新加入的命令最好不要放在里面,而是放在board/中板子相关的文件夹里,比如board/samsung/smdk2440/

    如果需要灵活控制是否添加此命令,可加入条件编译,仿照U-Boot本身的做法定义以下宏:

    1
    #define CONFIG_CMD_MYCMD

    这个定义可以放在板子的头文件中,也可加入defconfig文件中。之后在Makefile文件中加入条件编译即可:

    1
    obj-$(CONFIG_CMD_MYCMD) += mycmd.o

    运行特定命令

    要实现自动下载,需要使用一个命令代替一系列命令,这就要求能够在程序中自动运行特定命令。U-Boot提供了一个方便的接口函数来实现这一目的:

    1
    2
    3
    4
    5
    6
    7
    8
    /*
    * Run a command using the selected parser.
    *
    * @param cmd Command to run
    * @param flag Execution flags (CMD_FLAG_...)
    * @return 0 on success, or != 0 on error.
    */
    int run_command(const char *cmd, int flag);

    只需调用此函数即可运行特定的命令。

    自动下载程序

    最后给出完整版的自动下载程序的实现代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    #include <common.h>
    #include <command.h>

    static int do_download(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    {
    int i;

    if(argc == 1)
    printf("param: u : U-Boot; l : Linux; f : File System. ");

    const char * const cmd_uboot[5] = {
    "nfs 30000000 /home/gmf/nfs/u-boot.bin",
    "protect off all",
    "erase 0 +$filesize",
    "cp.b 30000000 0 $filesize",
    "reset",
    };

    const char * const cmd_linux[4] = {
    "nfs 30008000 /home/gmf/nfs/uImage",
    "nand erase 60000 300000",
    "nand write.jffs2 30008000 60000 300000",
    "bootm 30008000",
    };

    const char * const cmd_fs[4] = {
    "nfs 32000000 /home/gmf/nfs/ramdisk.gz",
    "nand erase 560000 $filesize",
    "nand write.jffs2 32000000 560000 $filesize",
    "bootd",
    };

    switch(*argv[1]) {
    case 'u':
    case 'U':
    for(i = 0; i < 5; i++)
    {
    printf(" ########## ");
    printf(cmd_uboot[i]);
    printf(" ########## ");
    run_command(cmd_uboot[i], 0);
    }
    break;

    case 'l':
    case 'L':
    for(i = 0; i < 4; i++)
    {
    printf(" ########## ");
    printf(cmd_linux[i]);
    printf(" ########## ");
    run_command(cmd_linux[i], 0);
    }
    break;

    case 'f':
    case 'F':
    for(i = 0; i < 4; i++)
    {
    printf(" ########## ");
    printf(cmd_fs[i]);
    printf(" ########## ");
    run_command(cmd_fs[i], 0);
    }
    break;
    }
    return 0;
    }


    U_BOOT_CMD(
    download, 2, 1, do_download,
    "Download File (Uboot, Linux or FS)",
    " - Download File: u : U-Boot; l : Linux; f : File System. "
    );

    此处实现了自动下载u-boot.bin文件、uImage文件和ramdisk.gz文件,分别输入download udownload ldownload f即可。命令执行序列位于cmd_ubootcmd_linuxcmd_fs数组中。此代码结构很好进行扩展,如要加入新的选项,仿照目前的结构添加即可。

  • 相关阅读:
    jdbc在项目中的应用
    第五次作业-springmvc对表单的获取
    jquery的文档处理(部分)
    测试报告怎么写合理
    WebService的简单应用
    hdu--5078--orz
    hdu--5074--dp
    hdu--5108--数论
    hdu--5072--容斥原理
    hdu--3853--概率dp
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7081043.html
Copyright © 2011-2022 走看看