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"的一個映射。
修改點:
通過環境變量定義菜單的選項,非常不直觀,通過以下方式自定義一個結構體,看起來就直觀很多。
通過定義一個bootmenu_item 類型的數組,直觀的展現菜單選項的內容。bootmenu_create()中將解析環境變量修改爲解析定義的數組即可。
2.bootmenu_show()函數
源代碼在確定用戶選擇的entry後,選擇該entry的command字符串,然後執行run_command(command, 0)命令,完成命令的執行。
修改點:
通過上面自定義的結構體,完成一個command_key和command_fun的映射。然後自己實現一個exec_command)()函數。由於框架幫我們匹配到了command_key,所以該函數主要是通過key找到對應的fun函數並執行。
3.bootmenu_show()函數
源碼中,在執行完命令後,函數直接返回,那麼菜單也不再顯示,直接進入了uboot命令行界面。
修改點:
在執行完後,如果有些選項,我們需要再次顯示,那麼可以通過goto語句,跳到該函數的入口處,重新執行整個流程,從而打印出了整個菜單。
通過以上的修改,就實現了利用uboot中的菜單框架,自定義實現了自己的uboot菜單,非常方便。