diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/develop/cedit.rst | 169 | ||||
| -rw-r--r-- | doc/develop/expo.rst | 48 | ||||
| -rw-r--r-- | doc/develop/index.rst | 1 | ||||
| -rw-r--r-- | doc/usage/cmd/cedit.rst | 117 |
4 files changed, 321 insertions, 14 deletions
diff --git a/doc/develop/cedit.rst b/doc/develop/cedit.rst new file mode 100644 index 00000000000..63dff9d3f14 --- /dev/null +++ b/doc/develop/cedit.rst @@ -0,0 +1,169 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Configuration Editor +==================== + +Introduction +------------ + +U-Boot provides a configuration editor which allows settings to be changed in +a GUI or text environment. + + +This feature is still in development and has a number of limitations. For +example, cedit only supports menu items (there is no numeric or text entry), +provides no support for colour text and does not support scrolling. Still it is +possible to use it for simple applications. + + +Overview +-------- + +The configuration editor makes use of :doc:`expo` to build a description of the +configuration screens and allow user to interact with it. + +To create a single-scene cedit for your application: + +#. Design the scene, i.e. the objects that need to be present and what their + possible values are + +#. Enter this in .dts format + +#. Create a header file containing the IDs + +#. Run the 'expo.py' tool to generate a .dtb file containing the layout, which + can be used by U-Boot + +#. Use the :doc:`../usage/cmd/cedit` to create the cedit, read the settings, + present the cedit to the user and save the settings afterwards. + +Each of these is described in a separate section. See :ref:`expo_example` for +an example file. + + +Design a scene +-------------- + +Using a piece of paper or a drawing tool, lay out the objects you want in your +scene. Typically you will use the default layout engine, which simply puts items +one after the other from top to bottom. So use a single column and show the +prompt and value for each object. + +For menu items, show one of the values, but keep in mind what else you need. + + +Create an expo-format file +-------------------------- + +The description is in the form of a devicetree file, as documented at +:ref:`expo_format`. Since everything in an expo has an ID number (an integer +greater than 1) the description is written terms of these IDs. They each have +an enum value. which is typically taken care of by the `expo.py` tool. + +The expo should have a `scenes` node with a named scene as a subnode. Within the +scene, add properties for the scene, then a subnode for each object in the +scene. + +All object nodes require an `id` value and a `type` property. Other properties +depend on the type. For example, a menu has a `title` and an `item-label` list +proving the text for the menu items, as well as an `item-id` list providing the +ID of each menu item, so it can be selected. + +Text properties may have two variants. For example `title` specifies the title +of a menu, but you can instead use `title-id` to specify the string ID to use as +the title. String are defined in a separate area, common to the whole expo, +which contains a subnode for each string. Within that subnode are the ID and the +`value` (i.e. the text). For now only English is supported, but in future it may +be possible to append a language identifier to provide other values (e.g. +'value-es' for Spanish). + + +Create an ID header-file +------------------------ + +Expo needs to know the integer value to use for every ID referenced in your +expo-format file. For example, if you have defined a `cpu-speed` node with an +id of `ID_CPU_SPEED`, then Expo needs to know the value of `ID_CPU_SPEED`. + +When you write C code to use the expo, you may need to know the IDs. For +example, to find which value the user selected in `cpu-speed` menu, you must +use the `ID_CPU_SPEED` ID. The ID is the only way to refer to anything in Expo. + +Since we need a shared set of IDs, it is best to have a header file containing +them. Expo supports doing this with an enum, where every ID is listed in the +enum:: + + enum { + ZERO, + + ID_PROMPT, + + ID_SCENE1, + ID_SCENE1_TITLE, + ... + }; + +The C compiler can parse this directly. The `expo.py` tool parses it for expo. + +Create a header file containing every ID mentioned in your expo. Try to group +related things together. + + +Build the expo layout +--------------------- + +Use the `expo.py` tool to build a .dtb for your expo:: + + ./tools/expo.py -e expo_ids.h -l expo_layout.dts -o expo.dtb + +This uses the enum in the provided header file to get the ID numbers, grabs +the `.dts` file, inserts the ID numbers and then uses the devicetree compiler to +build a `.dtb` file. + +If you get an error:: + + Devicetree compiler error: + Error: <stdin>:9.19-20 syntax error + FATAL ERROR: Unable to parse input tree + +that means that something is wrong with your syntax, or perhaps you have an ID +in the `.dts` file that is not mentioned in your enum. Check both files and try +again. + + +Use the command interface +------------------------- + +See the :doc:`../usage/cmd/cedit` command for information on available commands. +Typically you will use `cedit load` to load the `.dtb` file and `cedit run` to +let the user interact with it. + + +Multiple scenes +--------------- + +Expo supports multiple scenes but has no pre-determined way of moving between +them. You could use selection of a menu item as a signal to change the scene, +but this is not currently implemented in the cedit code (see `cedit_run()`). + + +Themes +------ + +The configuration editor uses simple expo themes. The theme is read from +`/bootstd/cedit-theme` in the devicetree. + + +Reading and writing settings +---------------------------- + +Cedit provides several options for persistent settings: + +- Writing an FDT file to a filesystem +- Writing to U-Boot's environment variables, which are then typically stored in + a persistent manner +- Writing to CMOS RAM registers (common on x86 machines) + +For now, reading and writing settings is not automatic. See the +:doc:`../usage/cmd/cedit` for how to do this on the command line or in a +script. diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst index 2ac4af232da..f13761995d3 100644 --- a/doc/develop/expo.rst +++ b/doc/develop/expo.rst @@ -317,6 +317,18 @@ id Specifies the ID of the object. This is used when referring to the object. +Where CMOS RAM is used for reading and writing settings, the following +additional properties are required: + +start-bit + Specifies the first bit in the CMOS RAM to use for this setting. For a RAM + with 0x100 bytes, there are 0x800 bit locations. For example, register 0x80 + holds bits 0x400 to 0x407. + +bit-length + Specifies the number of CMOS RAM bits to use for this setting. The bits + extend from `start-bit` to `start-bit + bit-length - 1`. Note that the bits + must be contiguous. Menu nodes have the following additional properties: @@ -358,6 +370,9 @@ The `expo_arrange()` function can be called to arrange the expo objects in a suitable manner. For each scene it puts the title at the top, the prompt at the bottom and the objects in order from top to bottom. + +.. _expo_example: + Expo format example ~~~~~~~~~~~~~~~~~~~ @@ -367,22 +382,27 @@ strings are provided inline in the nodes where they are used. :: - #define ID_PROMPT 1 - #define ID_SCENE1 2 - #define ID_SCENE1_TITLE 3 + /* this comment is parsed by the expo.py tool to insert the values below + + enum { + ZERO, + ID_PROMPT, + ID_SCENE1, + ID_SCENE1_TITLE, - #define ID_CPU_SPEED 4 - #define ID_CPU_SPEED_TITLE 5 - #define ID_CPU_SPEED_1 6 - #define ID_CPU_SPEED_2 7 - #define ID_CPU_SPEED_3 8 + ID_CPU_SPEED, + ID_CPU_SPEED_TITLE, + ID_CPU_SPEED_1, + ID_CPU_SPEED_2, + ID_CPU_SPEED_3, - #define ID_POWER_LOSS 9 - #define ID_AC_OFF 10 - #define ID_AC_ON 11 - #define ID_AC_MEMORY 12 + ID_POWER_LOSS, + ID_AC_OFF, + ID_AC_ON, + ID_AC_MEMORY, - #define ID_DYNAMIC_START 13 + ID_DYNAMIC_START, + */ &cedit { dynamic-start = <ID_DYNAMIC_START>; @@ -465,7 +485,7 @@ Some ideas for future work: - Support unicode - Support curses for proper serial-terminal menus - Add support for large menus which need to scroll -- Add support for reading and writing configuration settings with cedit +- Update expo.py tool to check for overlapping names and CMOS locations .. Simon Glass <[email protected]> .. 7-Oct-22 diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 5b230d0321f..0d12484ace8 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -38,6 +38,7 @@ Implementation driver-model/index environment expo + cedit event global_data logging diff --git a/doc/usage/cmd/cedit.rst b/doc/usage/cmd/cedit.rst index 8e1110c7c77..f415b48699e 100644 --- a/doc/usage/cmd/cedit.rst +++ b/doc/usage/cmd/cedit.rst @@ -10,6 +10,11 @@ Synopis cedit load <interface> <dev[:part]> <filename> cedit run + cedit write_fdt <dev[:part]> <filename> + cedit read_fdt <dev[:part]> <filename> + cedit write_env [-v] + cedit read_env [-v] + cedit write_cmos [-v] [dev] Description ----------- @@ -22,6 +27,69 @@ It makes use of the expo subsystem. The description is in the form of a devicetree file, as documented at :ref:`expo_format`. +See :doc:`../../develop/cedit` for information about the configuration editor. + +cedit load +~~~~~~~~~~ + +Loads a configuration-editor description from a file. It creates a new cedit +structure ready for use. Initially no settings are read, so default values are +used for each object. + +cedit run +~~~~~~~~~ + +Runs the default configuration-editor event loop. This is very simple, just +accepting character input and moving through the objects under user control. +The implementation is at `cedit_run()`. + +cedit write_fdt +~~~~~~~~~~~~~~~ + +Writes the current user settings to a devicetree file. For each menu item the +selected ID and its text string are written. + +cedit read_fdt +~~~~~~~~~~~~~~ + +Reads the user settings from a devicetree file and updates the cedit with those +settings. + +cedit read_env +~~~~~~~~~~~~~~ + +Reads the settings from the environment variables. For each menu item `<name>`, +cedit looks for a variable called `c.<name>` with the ID of the selected menu +item. + +The `-v` flag enables verbose mode, where each variable is printed after it is +read. + +cedit write_env +~~~~~~~~~~~~~~~ + +Writes the settings to environment variables. For each menu item the selected +ID and its text string are written, similar to: + + setenv c.<name> <selected_id> + setenv c.<name>-str <selected_id's text string> + +The `-v` flag enables verbose mode, where each variable is printed before it is +set. + +cedit write_cmos +~~~~~~~~~~~~~~~~ + +Writes the settings to locations in the CMOS RAM. The locations used are +specified by the schema. See `expo_format_`. + +The `-v` flag enables verbose mode, which shows which CMOS locations were +updated. + +Normally the first RTC device is used to hold the data. You can specify a +different device by name using the `dev` parameter. + + Example ------- @@ -29,3 +97,52 @@ Example => cedit load hostfs - fred.dtb => cedit run + => cedit write_fdt hostfs - settings.dtb + +That results in:: + + / { + cedit-values { + cpu-speed = <0x00000006>; + cpu-speed-str = "2 GHz"; + power-loss = <0x0000000a>; + power-loss-str = "Always Off"; + }; + } + + => cedit read_fdt hostfs - settings.dtb + +This shows settings being stored in the environment:: + + => cedit write_env -v + c.cpu-speed=7 + c.cpu-speed-str=2.5 GHz + c.power-loss=12 + c.power-loss-str=Memory + => print + ... + c.cpu-speed=6 + c.cpu-speed-str=2 GHz + c.power-loss=10 + c.power-loss-str=Always Off + ... + + => cedit read_env -v + c.cpu-speed=7 + c.power-loss=12 + +This shows writing to CMOS RAM. Notice that the bytes at 80 and 84 change:: + + => rtc read 80 8 + 00000080: 00 00 00 00 00 2f 2a 08 ...../*. + => cedit write_cmos -v + Write 2 bytes from offset 80 to 84 + => rtc read 80 8 + 00000080: 01 00 00 00 08 2f 2a 08 ...../*. + => cedit read_cmos -v + Read 2 bytes from offset 80 to 84 + +Here is an example with the device specified:: + + => cedit write_cmos rtc@43 + => |
