UBOOT通用菜單menu的實現

1. 概述
在uboot中經常需要開發一個菜單,用來進行一些選項類的操作,如下圖所示

網上有很多介紹菜單的開發方法,但很多都是自己開發,沒有統一的開發框架。最近研究uboot代碼時發現,其實uboot(版本爲2016)代碼中有一個菜單框架,以及使用這個框架的一個具體例子,可以根據自己的需要進行適當的修改,用起來非常方便。
2.具體實現
菜單框架代碼位於/common/menu.c文件中,這個是一個菜單框架,提供了對外的一些使用接口。
使用這個框架代碼的實例代碼是位於/cmd/bootmenu.c,裏面通過使用框架,完成了一個簡單的菜單

但這個實例代碼在實際使用過程中,個人認爲存在幾個不足
1.每個菜單項都是以環境變量的方式保存,不是很直觀
2.執行命令時,只能是調用run_command()執行基本的boot命令,不能將菜單和具體的某個實現函數關聯到一起。
3.不能進行菜單的級聯
4.執行完菜單選項後,不能繼續回到當前菜單界面。

針對上面的幾個問題,把bootmenu.c中的代碼修改一下,就可以實現一個很方便的菜單。
修改的思路如下:
1.bootmenu_create()函數
源代碼是通過對環境變量解析,循環獲取bootmenu_entry,然後創建entry。entry中,有兩個關鍵字段title和command,主要對這兩個字段進行賦值。也就是完成對"key-value"的一個映射。
修改點:
通過環境變量定義菜單的選項,非常不直觀,通過以下方式自定義一個結構體,看起來就直觀很多。
struct bootmenu_item
{
    char title[64];             /* title of entry */
    char command_key[64];       /* hush command of entry */
    void (*command_fun) (void);
};
static struct bootmenu_item items[] = {
    {"Modify Net Parameters""modify_net_paras", modify_net_paras},
    {"Download Boot""download_boot", download_boot},
    {"Download Image""download_image", download_image},
    {"Download DTB""download_dtb", download_dtb},
    {"U-Boot console", ENTER_CONSOLE, enter_console},
    {"Exit", EXIT_MENU, exit_menu},
};

通過定義一個bootmenu_item 類型的數組,直觀的展現菜單選項的內容。bootmenu_create()中將解析環境變量修改爲解析定義的數組即可。

2.bootmenu_show()函數
源代碼在確定用戶選擇的entry後,選擇該entry的command字符串,然後執行run_command(command, 0)命令,完成命令的執行。
修改點:
通過上面自定義的結構體,完成一個command_keycommand_fun的映射。然後自己實現一個exec_command)()函數。由於框架幫我們匹配到了command_key,所以該函數主要是通過key找到對應的fun函數並執行。
static void exec_command(char *command_key)
{
    int i = 0;
    for (i = 0; i < sizeof(items) / sizeof(struct bootmenu_item); i++)
    {
        if (!strcmp(items[i].command_key, command_key))
        {
            items[i].command_fun();
            break;
        }
    }
}

3.bootmenu_show()函數
源碼中,在執行完命令後,函數直接返回,那麼菜單也不再顯示,直接進入了uboot命令行界面。
修改點:
在執行完後,如果有些選項,我們需要再次顯示,那麼可以通過goto語句,跳到該函數的入口處,重新執行整個流程,從而打印出了整個菜單。

通過以上的修改,就實現了利用uboot中的菜單框架,自定義實現了自己的uboot菜單,非常方便。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章