Step 5 : Shell on Zephyr with QEMU
In this program, you are going to learn
What configurations needs to be added to enable shell?
How to do pre-build and post-build checks ?
How to execute commands on Zephyr shell?
How to add our own commands to execute in shell?
Topics in this section,
Add the following configurations in prj.conf to enable the shell on Zephyr build.
(.venv) test:zephyr$ pwd
$HOME/zephyrproject/zephyr
(.venv) test:zephyr$ vi samples/hello_world/prj.conf
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_SHELL_HISTORY=y
CONFIG_SHELL_CMDS_RESIZE=y
In this section we will see how to do pre-build checks.
Check whether the configurations required to enable shell for zephyr is added or not in prj.conf
CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_SHELL_HISTORY=y CONFIG_SHELL_CMDS_RESIZE=y
Check for the location of location in zephyr-sdk-0.16.4 directory
(.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
run west build command to build the application.
(.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
In this section we will see how to do post-build checks
Here we will see how to do static post build checks
Lets check for the location of the final application target image to make sure the build is completed successfully without any errors.
(.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
Here we will see how to do runtime post-build checks
Run the image using the west command.
(.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..
We can confirm the application is successfully loaded without any errors if the prompt is displayed on the virtual environment.
uart:~$
In this section, we will see about zephyr shell commands in detail.
“cycles” subcommand is used to give information about the kernel cycles.
uart:~$ kernel cycles
cycles: 976922951 hw cycles
“stacks” subcommand is used to list the thread stack usage.
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.
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 %)
“list” subcommand is used to list the configured devices.
uart:~$ device list
devices:
- ioapicfec00000 (READY)
- loapicfee00000 (READY)
- uart2f8 (READY)
- uart3f8 (READY)
In this section we will see how to see our own command in zephyr shell.
Add the following instructions in main.c
(.venv) test:zephyr$ pwd
$HOME/zephyrproject/zephyr
(.venv) test:zephyr$ vi samples/hello_world/src/main.c
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
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);
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.
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.
run west build to build the application.
(.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
run “west” command to run the application.
(.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.
uart:~$ hello
Hello, World!