Feature : Shell ================== .. tab-set:: .. tab-item:: Shell on Zephyr with RPI-4B * 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_rpi4b_feature1_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_rpi4b_feature1_1: .. tab-set:: .. tab-item:: Do Pre-build checks * In this section we will see how to do pre-build checks. .. _zephyr_rpi4b_feature1_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_rpi4b_feature1_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_rpi4b_feature1_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 rpi4b samples/hello_world/ -- west build: making build dir /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build pristine -- west build: generating a build system Loading Zephyr default modules (Zephyr base). -- Application: /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/samples/hello_world -- CMake version: 3.24.2 -- Found Python3: /home/wifi/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/wifi/.cache/zephyr -- Zephyr version: 3.6.0-rc2 (/home/wifi/zephyr_with_rpi4/zephyrproject/zephyr) -- Found west (found suitable version "1.2.0", minimum required is "0.14.0") -- Board: rpi_4b -- ZEPHYR_TOOLCHAIN_VARIANT not set, trying to locate Zephyr SDK -- Found host-tools: zephyr 0.16.4 (/home/wifi/double_thread_zephyr_build/zephyr-sdk-0.16.4) -- Found toolchain: zephyr 0.16.4 (/home/wifi/double_thread_zephyr_build/zephyr-sdk-0.16.4) -- Found Dtc: /home/wifi/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/wifi/zephyr_with_rpi4/zephyrproject/zephyr/boards/arm64/rpi_4b/rpi_4b.dts -- Generated zephyr.dts: /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/zephyr.dts -- Generated devicetree_generated.h: /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/include/generated/devicetree_generated.h -- Including generated dts.cmake file: /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/dts.cmake Parsing /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/Kconfig Loaded configuration /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/boards/arm64/rpi_4b/rpi_4b_defconfig Merged configuration /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/samples/hello_world/prj.conf Configuration saved to /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/.config Kconfig header saved to /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/include/generated/autoconf.h -- Found GnuLd: /home/wifi/double_thread_zephyr_build/zephyr-sdk-0.16.4/aarch64-zephyr-elf/bin/../lib/gcc/aarch64-zephyr-elf/12.2.0/../../../../aarch64-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/wifi/double_thread_zephyr_build/zephyr-sdk-0.16.4/aarch64-zephyr-elf/bin/aarch64-zephyr-elf-gcc -- Using ccache: /usr/bin/ccache -- Configuring done -- Generating done -- Build files have been written to: /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build -- west build: building application [1/119] Preparing syscall dependency handling [2/119] Generating include/generated/version.h -- Zephyr version: 3.6.0-rc2 (/home/wifi/zephyr_with_rpi4/zephyrproject/zephyr), build: v3.6.0-rc2-104-g793c507209eb [118/119] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used FLASH: 0 GB 0 GB RAM: 155652 B 512 KB 29.69% IDT_LIST: 0 GB 32 KB 0.00% Generating files from /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/zephyr.elf for board: rpi_4b [119/119] cd /home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr && /home/wifi/zephyrproject/....k_init_priorities.py --elf-file=/home/wifi/zephyr_with_rpi4/zephyrproject/zephyr/build/zephyr/zephyr.elf .. _zephyr_rpi4b_feature1_3: .. tab-set:: .. tab-item:: Do Post-build checks * In this section we will see how to do post-build checks .. _zephyr_rpi4b_feature1_3_1: .. tab-set:: .. tab-item:: Static Post-build checks * Here we will see how to do static post build checks .. _zephyr_rpi4b_feature1_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/ -rwxrwxr-x 1 test test 39190 Jan 24 18:38 zephyr.bin -rw-rw-r-- 1 test test 23193 Jan 24 18:38 zephyr.dts -rw-rw-r-- 1 test test 3011 Jan 24 18:38 zephyr.dts.d -rw-rw-r-- 1 test test 97435 Jan 24 18:38 zephyr.dts.pre -rwxrwxr-x 1 test test 1023460 Jan 24 18:38 zephyr.elf -rw-rw-r-- 1 test test 399931 Jan 24 18:38 zephyr_final.map -rw-rw-r-- 1 test test 110346 Jan 24 18:38 zephyr.hex -rw-rw-r-- 1 test test 399931 Jan 24 18:38 zephyr.map -rwxrwxr-x 1 test test 1024056 Jan 24 18:38 zephyr_pre0.elf -rw-rw-r-- 1 test test 400481 Jan 24 18:38 zephyr_pre0.map -rw-rw-r-- 1 test test 4675 Jan 24 18:38 zephyr.stat .. _zephyr_rpi4b_feature1_3_2: .. tab-set:: .. tab-item:: Runtime Post-build checks * Here we will see how to do runtime post-build checks .. _zephyr_rpi4b_feature1_3_2_1: .. tab-set:: .. tab-item:: Flash the image * Go to main directory .. code-block:: c $ cd $HOME $ mkdir Zephyr_flash $ cd Zephyr_flash * Download and place these files using web link: * `bcm2711-rpi-4-b.dtb `_ * `bootcode.bin `_ * `start4.elf `_ * Alternatively download using wget command, .. code-block:: c $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bcm2711-rpi-4-b.dtb $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bootcode.bin $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start4.elf * Create the config.txt file and copy the below lines and save the file .. code-block:: c $ vi config.txt * Place the following contents in ``config.txt`` file. .. code-block:: c kernel=zephyr.bin arm_64bit=1 enable_uart=1 uart_2ndstage=1 * Copy the zephyr.bin file to Zephyr_flash directory .. code-block:: c $ cp /home/test/zephyrproject/zephyr/build/zephyr/zephyr.bin /home/Zephyr_flash * Copy all the below files to TF card(SD card) .. code-block:: c bcm2711-rpi-4-b.dtb bootcode.bin start4.elf config.txt zephyr.bin * Copy using ``cp`` command, .. code-block:: c $ cp Zephyr_flash/bcm2711-rpi-4-b.dtb /mnt/boot/ $ cp Zephyr_flash/bootcode.bin /mnt/boot/ $ cp Zephyr_flash/start4.elf /mnt/boot/ $ cp Zephyr_flash/config.txt /mnt/boot/ $ cp Zephyr_flash/zephyr.bin /mnt/boot/ * Disconnect the micro SD Card reader from Linux Desktop machine. * Insert SD Card to the RPI Board * Then, use serial usb cable to connect the RPI board and Linux Desktop machine. * After connecting, check whether ``/dev/ttyUSB0`` created or not. .. code-block:: c $ ls /dev/ttyUSB0 * Run minicom to access RPI board .. code-block:: c $ sudo minicom -D /dev/ttyUSB0 -b 115200 .. _zephyr_rpi4b_feature1_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_rpi4b_feature1_4: .. tab-set:: .. tab-item:: Commands in Zephyr shell * In this section, we will see about zephyr shell commands in detail. .. _zephyr_rpi4b_feature1_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: 541874435 hw cycles * "stacks" subcommand is used to list the thread stack usage. .. code-block:: c uart:~$ kernel stacks 0x20000430 sysworkq (real size 1024): unused 816 usage 208 / 1024 (20 %) 0x20000100 shell_uart (real size 2048): unused 872 usage 1176 / 2048 (57 %) 0x200002a0 idle (real size 256): unused 168 usage 88 / 256 (34 %) 0x200011a0 IRQ 00 (real size 2048): unused 1652 usage 396 / 2048 (19 %) * "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: 1529 since last call Threads: 0x20000430 sysworkq options: 0x0, priority: -1 timeout: 0 state: pending, entry: 0x8005681 stack size 1024, unused 816, usage 208 / 1024 (20 %) *0x20000100 shell_uart options: 0x0, priority: 14 timeout: 0 state: queued, entry: 0x8001d81 stack size 2048, unused 872, usage 1176 / 2048 (57 %) 0x200002a0 idle options: 0x1, priority: 15 timeout: 0 state: , entry: 0x800782f stack size 256, unused 168, usage 88 / 256 (34 %) .. _zephyr_rpi4b_feature1_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: - rcc40021000 (READY) - reset-controller (READY) - interrupt-controller40021800 (READY) - gpio50001400 (READY) - gpio50001000 (READY) - gpio50000c00 (READY) - gpio50000800 (READY) - gpio50000400 (READY) - gpio50000000 (READY) - serial40004400 (READY) - serial40013800 (READY) .. _zephyr_rpi4b_feature1_4_3: .. tab-set:: .. tab-item:: Commands to print interrupt information .. code-block:: c .. _zephyr_rpi4b_feature1_4_4: .. tab-set:: .. tab-item:: Commands to print how many HW entity like clocks,timers are present .. code-block:: c .. _zephyr_rpi4b_feature1_4_5: .. tab-set:: .. tab-item:: Commands to print Overall RAM and SRAM usage .. code-block:: c .. _zephyr_rpi4b_feature1_4_6: .. tab-set:: .. tab-item:: Commands to print information about flash space .. code-block:: c .. _zephyr_rpi4b_feature1_4_7: .. tab-set:: .. tab-item:: Commands to print information about network interfaces .. code-block:: c .. _zephyr_rpi4b_feature1_4_8: .. tab-set:: .. tab-item:: Commands to print information about wifi interfaces .. code-block:: c .. _zephyr_rpi4b_feature1_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_rpi4b_feature1_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_rpi4b_feature1_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 its 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_rpi4b_feature1_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 rpi_4b samples/hello_world/ .. _zephyr_rpi4b_feature1_5_4: .. tab-set:: .. tab-item:: Executing our own command in zephyr shell * Go to main directory .. code-block:: c $ cd $HOME $ mkdir Zephyr_flash $ cd Zephyr_flash * Download and place these files using web link: * `bcm2711-rpi-4-b.dtb `_ * `bootcode.bin `_ * `start4.elf `_ * Alternatively download using wget command, .. code-block:: c $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bcm2711-rpi-4-b.dtb $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bootcode.bin $ wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start4.elf * Create the config.txt file and copy the below lines and save the file .. code-block:: c $ vi config.txt * Place the following contents in ``config.txt`` file. .. code-block:: c kernel=zephyr.bin arm_64bit=1 enable_uart=1 uart_2ndstage=1 * Copy the zephyr.bin file to Zephyr_flash directory .. code-block:: c $ cp /home/test/zephyrproject/zephyr/build/zephyr/zephyr.bin /home/Zephyr_flash * Copy all the below files to TF card(SD card) .. code-block:: c bcm2711-rpi-4-b.dtb bootcode.bin start4.elf config.txt zephyr.bin * Copy using ``cp`` command, .. code-block:: c $ cp Zephyr_flash/bcm2711-rpi-4-b.dtb /mnt/boot/ $ cp Zephyr_flash/bootcode.bin /mnt/boot/ $ cp Zephyr_flash/start4.elf /mnt/boot/ $ cp Zephyr_flash/config.txt /mnt/boot/ $ cp Zephyr_flash/zephyr.bin /mnt/boot/ * Disconnect the micro SD Card reader from Linux Desktop machine. * Insert SD Card to the RPI Board * Then, use serial usb cable to connect the RPI board and Linux Desktop machine. * After connecting, check whether ``/dev/ttyUSB0`` created or not. .. code-block:: c $ ls /dev/ttyUSB0 * Run minicom to access RPI board .. code-block:: c $ sudo minicom -D /dev/ttyUSB0 -b 115200 * run "hello" on the minicom console to execute our own command. .. code-block:: c uart:~$ hello Hello, World!