Zephyr building blocks
Zephyr RTOS building blocks :: Device Tree Source :: Kconfig :: cmake :: `west` manifest files
Contents
^ OVERVIEW
Local NN wiki page to hold notes on Zephyr RTOS explorations and Zephyr building blocks. These "building blocks" are worth mentioning here in overview, but this page and several related ones Ted needs to review and condense. They're not well organized yet. This disorganization is more obvious now with a greater though not complete understanding of Zephyr RTOS' architecture and chosen hardware and software paradigms. Building blocks of Zephyr worth note:
- `west` and cmake
- Device Tree Source (DTS)
- Kconfig
- Zephyr Device Drivers API
- Zephyr modules
A further post few weeks into Zephyr development, this blog post references a prior post in which setting up Zephyr build environment and project for first time is covered:
'uart_poll_in()' Zephyr peripheral library routine:
2022-12-08
We'll need to move, reorganize and clean up a bunch of Zephyr related notes, but for now here is a link which can / may go into a yet-to-create page "Zephyr Intermediate Topics" page:
- https://blog.golioth.io/how-to-build-your-zephyr-app-in-a-standalone-folder/ Golioth dot io blog post "How to build Zephyr app in standalone dir"
^ Zephyr Latest Notes
Really good discussion of Zephyr device tree issues, answers some question (brings some bad news at least as of Zephyr at its 2020 Feb release) regarding devices not being un-initializable, re-initializable at run time. This means reboot is needed when device really fails to initialize . . . remember this github issue number 22941:
A post referring to nRF9160 low power and sleep modes:
- https://devzone.nordicsemi.com/f/nordic-q-a/45690/nrf9160-sleep-mode < - - over three years old but yet potentially helpful
-
"...both the edrx & psm mode will make you go into system on low power (aka system on idle) when they are in sleep."
Looks like there are enough questions and posts, resources to review that we should start a notes page for Zephyr and Nordic ncs sleep modes.
- = * * * = -
Nordic Semi Secure Partition Manager (SPM) library, for Cortex-M33 and related parts:
To review . . .
-
Zephyr was unable to find the toolchain. Is the environment misconfigured? #39051
Post on Zephyr based app "Unable to establish multiple MQTT client broker connections". Looks like multiple MQTT connections are possible:
2022-02-21 Monday Multi-image OTA updates, application core and network core specifically:
^ Zephyr In-Tree Drivers
Starting notes here with a commonly used bus peripheral and protocol driver, Zephyr's in-tree I2C driver. First link is to a specific routine for burst writes:
Note above link is Zephyr 'latest' version, a moving target, following link is version 2.6.0:
^ Zephyr Modules
Zephyr RTOS provides an interactive shell code module. This represents an advanced CLI which can be used via UART and some other physical bus interfaces:
QUESTION: how using Zephyr's sensor driver API may we read back more than a sensor_value
e.g. two integers worth of data with a call to [device_name]_channel_get() API? Could this following link to device specific API extensions hold an answer?
Mention of run time mutable parts in this Zephyr documentation page:
Sensor API and sensor_value data structure in Zephyr project (release 2.6.0):
^ timing facilities
Timing Facilities
Timing and Zephyr kernel clocks, this first page however may be for a very old version of Zephyr. The 2.6.0 page is current for 2021 Q4:
- https://docs.zephyrproject.org/2.6.0/reference/timing_functions/index.html?highlight=kernel%20timing
2022-02-21:
^ SPI interface
STMicro IIS2DH sensor and SPI interface
- https://docs.zephyrproject.org/2.6.0/reference/peripherals/spi.html?highlight=spi
- https://docs.zephyrproject.org/2.6.0/reference/devicetree/bindings/sensor/st,iis2dh-spi.html?highlight=spi
^ USART references
"Hello world" example build command:
west build -b circuitdojo_feather_nrf9160ns samples/hello_world -p
Programming command:
newtmgr -c serial image upload build/zephyr/app_update.bin
In given example code directory, enable MCU bootloading with last line of following prj.conf file:
CONFIG_GPIO=y ## 2021-08-02 adding stanza per https://learn.sparkfun.com/tutorials/nrf9160-thing-plus-hookup-guide#example---blinky: CONFIG_BOOTLOADER_MCUBOOT=y
2021-10-05 Tuesday work to enable alternate USART for simple CLI:
2022-07-10 Note also there is a one-time `newtmgr` configuration step to inform this utility of the particular serial device to treat as the programmer to the targeted hardware. This set up step is mentioned in the first few exchanges of this Jared Wolff community forum post:
Also
The `newtmgr` port configuration command on Linux hosts take the form, from Zephyr project issues 9509:
@bfrog An example of proper connection parameters. sudo ./mcumgr image list --conntype=serial --connstring='dev=/dev/ttyACM0,baud=115200'
^ LIS2DH example project build errors
Build errors when attempting to compile LIS2DH sensor example with circuitdojo board as target board:
[192/197] Linking C executable zephyr/zephyr_prebuilt.elf Memory region Used Size Region Size %age Used FLASH: 32 KB 48 KB 66.67% SRAM: 5520 B 64 KB 8.42% IDT_LIST: 40 B 2 KB 1.95% [197/197] Linking C executable zephyr/zephyr.elf [24/159] Building C object CMakeFiles/app.dir/src/main.c.obj FAILED: CMakeFiles/app.dir/src/main.c.obj ccache /opt/zephyr-sdk-0.12.4/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -DBUILD_VERSION=v2.4.0-ncs2 -DEXT_API_MAGIC=0x281ee6de,0xb845acea,23298 -DFIRMWARE_INFO_MAGIC=0x281ee6de,0x8fcebb4c,23298 -DKERNEL -DNRF9160_XXAA -DNRF_TRUSTZONE_NONSECURE -DUSE_PARTITION_MANAGER=1 -D_FORTIFY_SOURCE=2 -D__PROGRAM_START -D__ZEPHYR__=1 -I/home/ted/projects/embedded/ncs/v1.4.1/zephyr/include -Izephyr/include/generated -I/home/ted/projects/embedded/ncs/v1.4.1/zephyr/soc/arm/nordic_nrf/nrf91 -I/home/ted/projects/embedded/ncs/v1.4.1/nrf/include -I/home/ted/projects/embedded/ncs/v1.4.1/modules/hal/cmsis/CMSIS/Core/Include -I/home/ted/projects/embedded/ncs/v1.4.1/modules/hal/nordic/nrfx -I/home/ted/projects/embedded/ncs/v1.4.1/modules/hal/nordic/nrfx/drivers/include -I/home/ted/projects/embedded/ncs/v1.4.1/modules/hal/nordic/nrfx/mdk -I/home/ted/projects/embedded/ncs/v1.4.1/modules/hal/nordic/. -isystem /home/ted/projects/embedded/ncs/v1.4.1/zephyr/lib/libc/minimal/include -isystem /opt/zephyr-sdk-0.12.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.2.0/include -isystem /opt/zephyr-sdk-0.12.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.2.0/include-fixed -Os -imacros /home/ted/projects/embedded/ncs/v1.4.1/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -mcpu=cortex-m33 -mthumb -mabi=aapcs -imacros /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-main -Wno-pointer-sign -Wpointer-arith -Wno-address-of-packed-member -Wno-unused-but-set-variable -Werror=implicit-int -fno-asynchronous-unwind-tables -fno-pie -fno-pic -fno-strict-overflow -fno-reorder-functions -fno-defer-pop -fmacro-prefix-map=/home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh=CMAKE_SOURCE_DIR -fmacro-prefix-map=/home/ted/projects/embedded/ncs/v1.4.1/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/home/ted/projects/embedded/ncs/v1.4.1=WEST_TOPDIR -ffunction-sections -fdata-sections -std=c99 -nostdinc -MD -MT CMakeFiles/app.dir/src/main.c.obj -MF CMakeFiles/app.dir/src/main.c.obj.d -o CMakeFiles/app.dir/src/main.c.obj -c /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c In file included from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/arch/arm/aarch32/arch.h:20, from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/arch/cpu.h:19, from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/kernel_includes.h:38, from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/kernel.h:17, from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/zephyr.h:18, from /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c:8: /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c: In function 'main': /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:297:40: error: 'DT_N_INST_0_st_lis2dh_P_label' undeclared (first use in this function) 297 | #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat)) | ^~~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:1911:38: note: in definition of macro 'DT_CAT' 1911 | #define DT_CAT(node_id, prop_suffix) node_id##prop_suffix | ^~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:496:27: note: in expansion of macro 'DT_PROP' 496 | #define DT_LABEL(node_id) DT_PROP(node_id, label) | ^~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c:53:51: note: in expansion of macro 'DT_LABEL' 53 | const struct device *sensor = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); | ^~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/sys/util_internal.h:105:26: note: in expansion of macro 'UTIL_PRIMITIVE_CAT' 105 | #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) | ^~~~~~~~~~~~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:297:31: note: in expansion of macro 'UTIL_CAT' 297 | #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat)) | ^~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c:53:60: note: in expansion of macro 'DT_INST' 53 | const struct device *sensor = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); | ^~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:297:40: note: each undeclared identifier is reported only once for each function it appears in 297 | #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat)) | ^~~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:1911:38: note: in definition of macro 'DT_CAT' 1911 | #define DT_CAT(node_id, prop_suffix) node_id##prop_suffix | ^~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:496:27: note: in expansion of macro 'DT_PROP' 496 | #define DT_LABEL(node_id) DT_PROP(node_id, label) | ^~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c:53:51: note: in expansion of macro 'DT_LABEL' 53 | const struct device *sensor = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); | ^~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/sys/util_internal.h:105:26: note: in expansion of macro 'UTIL_PRIMITIVE_CAT' 105 | #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) | ^~~~~~~~~~~~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/include/devicetree.h:297:31: note: in expansion of macro 'UTIL_CAT' 297 | #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat)) | ^~~~~~~~ /home/ted/projects/embedded/ncs/v1.4.1/zephyr/samples/sensor/lis2dh/src/main.c:53:60: note: in expansion of macro 'DT_INST' 53 | const struct device *sensor = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); | ^~~~~~~ [29/159] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/onoff.c.obj ninja: build stopped: subcommand failed. FATAL ERROR: command exited with status 1: /usr/bin/cmake --build /home/ted/projects/embedded/ncs/v1.4.1/build ted@localhost:~/projects/embedded/ncs/v1.4.1$
Search for DT_N_INST:
ted@indulkana:~/projects/embedded/ncs/v1.4.1$ grep -nr 'DT_N_INST[^_]' ./* ./zephyr/include/devicetree.h:297:#define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat)) ./zephyr/include/devicetree.h:1245: UTIL_CAT(DT_N_INST, DT_DASH(compat, NUM_OKAY)))
^ LIS2DH example code
ted@localhost:~/projects/embedded/ncs/v1.4.1$ grep -nr st_lis2dh ./* ./zephyr/drivers/sensor/lis2dh/lis2dh_spi.c:11:#define DT_DRV_COMPAT st_lis2dh ./zephyr/drivers/sensor/lis2dh/lis2dh_i2c.c:11:#define DT_DRV_COMPAT st_lis2dh ./zephyr/drivers/sensor/lis2dh/lis2dh_trigger.c:7:#define DT_DRV_COMPAT st_lis2dh ./zephyr/drivers/sensor/lis2dh/lis2dh.c:7:#define DT_DRV_COMPAT st_lis2dh ./zephyr/samples/shields/x_nucleo_iks01a2/src/main.c:22: const struct device *lsm303agr_a = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); ./zephyr/samples/sensor/lsm303dlhc/src/main.c:42: DT_LABEL(DT_INST(0, st_lis2dh))); ./zephyr/samples/sensor/lsm303dlhc/src/main.c:48: DT_LABEL(DT_INST(0, st_lis2dh))); Binary file ./zephyr/samples/sensor/lis2dh/src/.main.c.swp matches ./zephyr/samples/sensor/lis2dh/src/main.c:53: const struct device *sensor = device_get_binding(DT_LABEL(DT_INST(0, st_lis2dh))); ./zephyr/samples/sensor/lis2dh/src/main.c:57: DT_LABEL(DT_INST(0, st_lis2dh)));
^ Setting Up Revisit
This link from Zephyr's documentation home page / home site a good and detailed overview of the Zephyr RTOS project:
Detailed steps to install Zephyr's needed build tools and Zephyr SDK:
Board support for CircuitDojo nRF9160 Thing Plus is not available in either Nordic's ncs v1.4.1 SDK nor Zephyr's SDK which comes as part of Zephyr 2.6.0. Steps to locating an SDK which include board support and files for the Thing Plus include navigating the following URLs:
-
(1) https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/boards/index.html#boards
(2) https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/boards/arm/sparkfun_thing_plus_nrf9160/doc/index.html
(3) https://docs.jaredwolff.com/nrf9160-getting-started.html
(4) https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/tools/nordic_segger.html#nordic-segger
(5) https://github.com/nrfconnect/sdk-zephyr/blob/master/boards/arm/sparkfun_thing_plus_nrf9160/sparkfun_thing_plus_nrf9160_common.dts
Link (3) Jared Wolff does not spell out nor provide a direct link to an SDK supporting the nRF9160 Thing Plus.
Findings: Ok, Zephyr project's SDK, largely the firmware projects under the 'samples' directory contains support for CircuitDojo nRF9160 Thing Plus. This SDK however lacks the mcuboot option firmware build step and piece, so none of the Zephyr SDKs will build in a manner in which utility newtmgr
can be used to program given target board.
Zephyr RTOS Logger and Backend Features
- https://docs.zephyrproject.org/2.6.0/reference/logging/index.html#logger-backend-interface
- https://docs.zephyrproject.org/2.6.0/reference/logging/index.html#default-frontend
Zephyr's thread_analyzer when not configured to dump reports to printk() instead sends thread data to LOG_INF(). Excerpt from Zephyr file `./zephyr/subsys/debug/thread_analyzer.c`:
11 #include <kernel.h> 12 #include <debug/thread_analyzer.h> 13 #include <debug/stack.h> 14 #include <kernel.h> 15 #include <logging/log.h> 16 #include <stdio.h> 17 18 LOG_MODULE_REGISTER(thread_analyzer, CONFIG_THREAD_ANALYZER_LOG_LEVEL); 19 20 #if IS_ENABLED(CONFIG_THREAD_ANALYZER_USE_PRINTK) 21 #define THREAD_ANALYZER_PRINT(...) printk(__VA_ARGS__) 22 #define THREAD_ANALYZER_FMT(str) str "\n" 23 #define THREAD_ANALYZER_VSTR(str) (str)~/projects/zephyr-based/nrf$ vi ./applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZDebug.conf 24 #else 25 #define THREAD_ANALYZER_PRINT(...) LOG_INF(__VA_ARGS__) 26 #define THREAD_ANALYZER_FMT(str) str 27 #define THREAD_ANALYZER_VSTR(str) log_strdup(str) 28 #endif
Zephyr macro `LOG_INF` is in turn defined:
ted@localhost:~/projects/zephyr-based/z4-sandbox-kionix-work/zephyr$ grep -nr LOG_INF ./* | grep define ./include/logging/log.h:61:#define LOG_INF(...) Z_LOG(LOG_LEVEL_INF, __VA_ARGS__)~/projects/zephyr-based/nrf$ vi ./applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZDebug.conf
2022-03-08 TUE - We got to figure out where log levels beyond zero in value are defined, where is Zephyr's header file for its logging module or facility? . . .
Note also that ncs / Zephyr pelion client app has some extensive Kconfig settings in its prj.conf file:
~/projects/zephyr-based/nrf$ vi ./applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZDebug.conf
^ References
A useful C language facet tutorial, "Complex C Declarations" and untangling complex C declarations by one Brian Barto. This link present elsewhere on Neela Nurseries wiki given that this tutorial is so helpful:
./zephyr/doc/guides/dts/howtos.rst:710: #define I2C_DEV_INST DT_INST(0, vnd_i2c_device) ./zephyr/doc/guides/dts/howtos.rst:735: #define SPI_DEV_INST DT_INST(0, vnd_spi_device) # nRF91 Series > nRF9160 > Production Programming > Updating the modem # https://developer.arm.com/ip-products/processors/cortex-m/cortex-m33
Rohm Kionix header files: