Step 5 : Shell on Zephyr with QEMU ==================================== .. tab-set:: .. tab-item:: Shell on Zephyr with QEMU * In this program, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * What configurations needs to be added to enable shell? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to do pre-build and post-build checks ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to execute commands on Zephyr shell? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to add our own commands to execute in shell? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Step 4.1: Adding Configurations in prj.conf ` * :ref:`Step 4.2: Do Pre-build checks ` * :ref:`Step 4.2.1: Check configurations for shell added or not ` * :ref:`Step 4.2.2: Location of toolchain ` * :ref:`Step 4.3: Build the Application ` * :ref:`Step 4.4: Do Post-build checks ` * :ref:`Step 4.4.1: Static post build checks ` * :ref:`Step 4.4.1.1: Location of the final target image ` * :ref:`Step 4.4.2: Runtime post build checks ` * :ref:`Step 4.4.2.1: Load and Run the image ` * :ref:`Step 4.4.2.2: Confirm if the prompt is displayed ` * :ref:`Step 4.5: Commands in Zephyr shell ` * :ref:`Step 4.5.1: Commands to print kernel and thread related information ` * :ref:`Step 4.5.2: Commands to print device related information ` * :ref:`Step 4.5.3: Commands to print interrupt information ` * :ref:`Step 4.5.4: Commands to print how many HW entity like clocks,timers are present ` * :ref:`Step 4.5.5: Commands to print Overall RAM and SRAM usage ` * :ref:`Step 4.5.6: Commands to print information about flash space ` * :ref:`Step 4.5.7: Commands to print information about network interfaces ` * :ref:`Step 4.5.8: Commands to print information about wifi interfaces ` * :ref:`Step 4.6: Adding our own command in Zephyr shell ` * :ref:`Step 4.6.1: Adding main.c ` * :ref:`Step 4.6.2: Explanation of APIs used in main.c ` * :ref:`Step 4.6.3: Building the application ` * :ref:`Step 4.6.4: Executing our own command in zephyr shell ` .. _zephyr_qemu_step5_0: .. tab-set:: .. tab-item:: Adding Configurations in prj.conf * Add the following configurations in prj.conf to enable the shell on Zephyr build. .. code-block:: c (.venv) test:zephyr$ pwd $HOME/zephyrproject/zephyr (.venv) test:zephyr$ vi samples/hello_world/prj.conf .. tab-set:: .. tab-item:: prj.conf .. code-block:: c CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_SHELL_HISTORY=y CONFIG_SHELL_CMDS_RESIZE=y .. _zephyr_qemu_step5_1: .. tab-set:: .. tab-item:: Do Pre-build checks * In this section we will see how to do pre-build checks. .. _zephyr_qemu_step5_1_1: .. tab-set:: .. tab-item:: Check the configurations for shell are added or not * Check whether the configurations required to enable shell for zephyr is added or not in prj.conf .. tab-set:: .. tab-item:: prj.conf .. code-block:: c CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_SHELL_HISTORY=y CONFIG_SHELL_CMDS_RESIZE=y .. _zephyr_qemu_step5_1_2: .. tab-set:: .. tab-item:: Check the location of toolchain * Check for the location of location in zephyr-sdk-0.16.4 directory .. code-block:: c (.venv) test:zephyr$ ls -l $HOME/zephyr-sdk-0.16.4/aarch64-zephyr-elf/aarch64-zephyr-elf/bin/ total 17000 -rwxr-xr-x 2 test test 1357336 Nov 15 16:40 ar -rwxr-xr-x 2 test test 2500544 Nov 15 16:40 as -rwxr-xr-x 4 test test 2019136 Nov 15 16:40 ld -rwxr-xr-x 4 test test 2019136 Nov 15 16:40 ld.bfd -rwxr-xr-x 2 test test 1346128 Nov 15 16:40 nm -rwxr-xr-x 2 test test 1467888 Nov 15 16:40 objcopy -rwxr-xr-x 2 test test 2876656 Nov 15 16:40 objdump -rwxr-xr-x 2 test test 1357368 Nov 15 16:40 ranlib -rwxr-xr-x 2 test test 977144 Nov 15 16:40 readelf -rwxr-xr-x 2 test test 1467888 Nov 15 16:40 strip .. _zephyr_qemu_step5_2: .. tab-set:: .. tab-item:: Build the Application * run west build command to build the application. .. code-block:: c (.venv) test:zephyr$ pwd $HOME/zephyrproject/zephyr (.venv) test:zephyr$ west build -b qemu_x86 samples/hello_world [1/125] Preparing syscall dependency handling [3/125] Generating include/generated/version.h -- Zephyr version: 3.5.99 (/home/test/zephyr_with_qemu/zephyrproject/zephyr), build: zephyr-v3.5.0-4596-g8556ae5afece [124/125] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used RAM: 143392 B 31 MB 0.44% IDT_LIST: 0 GB 2 KB 0.00% Generating files from /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/zephyr.elf for board: qemu_x86 [125/125] cd /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr && /home/test/zephyr_with...it_priorities.py --elf-file=/home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/zephyr.elf .. _zephyr_qemu_step5_3: .. tab-set:: .. tab-item:: Do Post-build checks * In this section we will see how to do post-build checks .. _zephyr_qemu_step5_3_1: .. tab-set:: .. tab-item:: Static Post-build checks * Here we will see how to do static post build checks .. _zephyr_qemu_step5_3_1_1: .. tab-set:: .. tab-item:: Check the location of the final target image * Lets check for the location of the final application target image to make sure the build is completed successfully without any errors. .. code-block:: c (.venv) test:zephyr$ ls -l build/zep build/zephyr/ -rw-rw-r-- 1 test test 4178 Jan 23 17:02 zephyr.dts -rw-rw-r-- 1 test test 597 Jan 23 17:06 zephyr.dts.d -rw-rw-r-- 1 test test 5767 Jan 23 17:06 zephyr.dts.pre -rwxrwxr-x 1 test test 1009028 Jan 24 11:59 zephyr.elf -rw-rw-r-- 1 test test 308505 Jan 24 11:59 zephyr_final.map -rw-rw-r-- 1 test test 308505 Jan 24 11:59 zephyr.map -rwxrwxr-x 1 test test 1009096 Jan 24 11:59 zephyr_pre0.elf -rw-rw-r-- 1 test test 310164 Jan 24 11:59 zephyr_pre0.map -rw-rw-r-- 1 test test 3930 Jan 24 11:59 zephyr.stat .. _zephyr_qemu_step5_3_2: .. tab-set:: .. tab-item:: Runtime Post-build checks * Here we will see how to do runtime post-build checks .. _zephyr_qemu_step5_3_2_1: .. tab-set:: .. tab-item:: Load and Run the image * Run the image using the west command. .. code-block:: c (.venv) test:zephyr$ west build -t run -- west build: running target run [0/1] To exit from QEMU enter: CTRL+a, x[QEMU] CPU: qemu32,+nx,+pae SeaBIOS (version zephyr-v1.0.0-0-g31d4e0e-dirty-20200714_234759-fv-az50-zephyr) Booting from ROM.. .. _zephyr_qemu_step5_3_2_2: .. tab-set:: .. tab-item:: Confirm if the prompt is displayed or not * We can confirm the application is successfully loaded without any errors if the prompt is displayed on the virtual environment. .. code-block:: c uart:~$ .. _zephyr_qemu_step5_4: .. tab-set:: .. tab-item:: Commands in Zephyr shell * In this section, we will see about zephyr shell commands in detail. .. _zephyr_qemu_step5_4_1: .. tab-set:: .. tab-item:: Commands to print kernel and thread related information * "cycles" subcommand is used to give information about the kernel cycles. .. code-block:: c uart:~$ kernel cycles cycles: 976922951 hw cycles * "stacks" subcommand is used to list the thread stack usage. .. code-block:: c uart:~$ kernel stacks 0x1177c0 sysworkq (real size 1024): unused 688 usage 336 / 1024 (32 %) 0x10d000 shell_uart (real size 2048): unused 896 usage 1152 / 2048 (56 %) 0x10d540 idle (real size 320): unused 184 usage 136 / 320 (42 %) 0x11c358 IRQ 00 (real size 2048): unused 1624 usage 424 / 2048 (20 %) * "threads" subcommand is used to list kernel threads along with various information like priority, state and stack size. .. code-block:: c uart:~$ kernel threads Scheduler: 806822 since last call Threads: 0x1177c0 sysworkq options: 0x0, priority: -1 timeout: 0 state: pending, entry: 0x109091 stack size 1024, unused 688, usage 336 / 1024 (32 %) *0x10d000 shell_uart options: 0x0, priority: 14 timeout: 0 state: queued, entry: 0x1035fd stack size 2048, unused 896, usage 1152 / 2048 (56 %) 0x10d540 idle options: 0x1, priority: 15 timeout: 0 state: , entry: 0x10838c stack size 320, unused 184, usage 136 / 320 (42 %) .. _zephyr_qemu_step5_4_2: .. tab-set:: .. tab-item:: Commands to print device related information * "list" subcommand is used to list the configured devices. .. code-block:: c uart:~$ device list devices: - ioapicfec00000 (READY) - loapicfee00000 (READY) - uart2f8 (READY) - uart3f8 (READY) .. _zephyr_qemu_step5_4_3: .. tab-set:: .. tab-item:: Commands to print interrupt information .. code-block:: c .. _zephyr_qemu_step5_4_4: .. tab-set:: .. tab-item:: Commands to print how many HW entity like clocks,timers are present .. code-block:: c .. _zephyr_qemu_step5_4_5: .. tab-set:: .. tab-item:: Commands to print Overall RAM and SRAM usage .. code-block:: c .. _zephyr_qemu_step5_4_6: .. tab-set:: .. tab-item:: Commands to print information about flash space .. code-block:: c .. _zephyr_qemu_step5_4_7: .. tab-set:: .. tab-item:: Commands to print information about network interfaces .. code-block:: c .. _zephyr_qemu_step5_4_8: .. tab-set:: .. tab-item:: Commands to print information about wifi interfaces .. code-block:: c .. _zephyr_qemu_step5_5: .. tab-set:: .. tab-item:: Adding our own command in zephyr shell * In this section we will see how to see our own command in zephyr shell. .. _zephyr_qemu_step5_5_1: .. tab-set:: .. tab-item:: Adding main.c * Add the following instructions in main.c .. code-block:: (.venv) test:zephyr$ pwd $HOME/zephyrproject/zephyr (.venv) test:zephyr$ vi samples/hello_world/src/main.c .. tab-set:: .. tab-item:: main.c .. code-block:: c #include #include static int hello_cmd_handler(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(shell, "Hello, World!"); return 0; } SHELL_CMD_REGISTER(hello, NULL, "Prints 'Hello, World!'", hello_cmd_handler); .. _zephyr_qemu_step5_5_2: .. tab-set:: .. tab-item:: Explanation of APIs in main.c .. code-block:: c static int hello_cmd_handler(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(shell, "Hello, World!"); return 0; } * This defines a function named hello_cmd_handler, which will be the handler for the custom shell command. * The function does not use the argc and argv parameters, so "ARG_UNUSED(argc)" and "ARG_UNUSED(argv)" are used to avoid compiler warnings about unused parameters. * "shell_print" is used to print the "Hello, World!" message to the shell. .. code-block:: c SHELL_CMD_REGISTER(hello, NULL, "Prints 'Hello, World!'", hello_cmd_handler); * This line registers the hello command with the Zephyr shell. * The SHELL_CMD_REGISTER macro takes four parameters: * hello: The name of the command. Users will type this command in the shell. * NULL: The subcommands. In this case, there are no subcommands, so it's set to NULL. * "Prints 'Hello, World!'": A description of the command, which will be displayed when users type help in the shell. * hello_cmd_handler: The function that will handle the command. .. _zephyr_qemu_step5_5_3: .. tab-set:: .. tab-item:: Building the application * run west build to build the application. .. code-block:: c (.venv) test:zephyr$ west build -b qemu_x86 samples/hello_world -- west build: generating a build system Loading Zephyr default modules (Zephyr base). -- Application: /home/test/zephyr_with_qemu/zephyrproject/zephyr/samples/hello_world -- CMake version: 3.24.2 -- Found Python3: /home/test/zephyr_with_qemu/zephyrproject/.venv/bin/python3 (found suitable version "3.10.7", minimum required is "3.8") found components: Interpreter -- Cache files will be written to: /home/test/.cache/zephyr -- Zephyr version: 3.5.99 (/home/test/zephyr_with_qemu/zephyrproject/zephyr) -- Found west (found suitable version "1.2.0", minimum required is "0.14.0") -- Board: qemu_x86 -- ZEPHYR_TOOLCHAIN_VARIANT not set, trying to locate Zephyr SDK -- Found host-tools: zephyr 0.16.4 (/home/test/double_thread_zephyr_build/zephyr-sdk-0.16.4) -- Found toolchain: zephyr 0.16.4 (/home/test/double_thread_zephyr_build/zephyr-sdk-0.16.4) -- Found Dtc: /home/test/double_thread_zephyr_build/zephyr-sdk-0.16.4/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.6.0", minimum required is "1.4.6") -- Found BOARD.dts: /home/test/zephyr_with_qemu/zephyrproject/zephyr/boards/x86/qemu_x86/qemu_x86.dts -- Generated zephyr.dts: /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/zephyr.dts -- Generated devicetree_generated.h: /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/include/generated/devicetree_generated.h -- Including generated dts.cmake file: /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/dts.cmake Parsing /home/test/zephyr_with_qemu/zephyrproject/zephyr/Kconfig Loaded configuration /home/test/zephyr_with_qemu/zephyrproject/zephyr/boards/x86/qemu_x86/qemu_x86_defconfig Merged configuration /home/test/zephyr_with_qemu/zephyrproject/zephyr/samples/hello_world/prj.conf Configuration saved to /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/.config Kconfig header saved to /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/include/generated/autoconf.h -- Found GnuLd: /home/test/double_thread_zephyr_build/zephyr-sdk-0.16.4/x86_64-zephyr-elf/bin/../lib/gcc/x86_64-zephyr-elf/12.2.0/../../../../x86_64-zephyr-elf/bin/ld.bfd (found version "2.38") -- The C compiler identification is GNU 12.2.0 -- The CXX compiler identification is GNU 12.2.0 -- The ASM compiler identification is GNU -- Found assembler: /home/test/double_thread_zephyr_build/zephyr-sdk-0.16.4/x86_64-zephyr-elf/bin/x86_64-zephyr-elf-gcc CMake Warning at /home/test/zephyr_with_qemu/zephyrproject/zephyr/subsys/random/CMakeLists.txt:12 (message): Warning: CONFIG_TIMER_RANDOM_GENERATOR is not a truly random generator. This capability is not secure and it is provided for testing purposes only. Use it carefully. -- Using ccache: /usr/bin/ccache -- Configuring done -- Generating done -- Build files have been written to: /home/test/zephyr_with_qemu/zephyrproject/zephyr/build -- west build: building application [1/125] Preparing syscall dependency handling [3/125] Generating include/generated/version.h -- Zephyr version: 3.5.99 (/home/test/zephyr_with_qemu/zephyrproject/zephyr), build: zephyr-v3.5.0-4596-g8556ae5afece [124/125] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used RAM: 143392 B 31 MB 0.44% IDT_LIST: 0 GB 2 KB 0.00% Generating files from /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/zephyr.elf for board: qemu_x86 [125/125] cd /home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr && /home/test/zephyr_with...it_priorities.py --elf-file=/home/test/zephyr_with_qemu/zephyrproject/zephyr/build/zephyr/zephyr.elf .. _zephyr_qemu_step5_5_4: .. tab-set:: .. tab-item:: Executing our own command in zephyr shell * run "west" command to run the application. .. code-block:: c (.venv) wifi:zephyr$ west build -t run -- west build: running target run [0/1] To exit from QEMU enter: CTRL+a, x[QEMU] CPU: qemu32,+nx,+pae SeaBIOS (version zephyr-v1.0.0-0-g31d4e0e-dirty-20200714_234759-fv-az50-zephyr) Booting from ROM.. *** Booting Zephyr OS build zephyr-v3.5.0-4596-g8556ae5afece *** uart:~$ * run "hello" to execute our own zephyr shell command. .. code-block:: c uart:~$ hello Hello, World!