====== Zephyr ====== ===== Länkar ===== * [[https://github.com/Utedass/zephyr-workspace]] -- My own devcontainer setup for Zephyr development * [[https://embedded.fm/episodes/475?rq=zephyr]] -- Nämner bland annat att det finns några tänkta sätt att strukturera sina projekt för att inte blanda in sin projekt-kod i zephyr-repot * [[https://www.youtube.com/watch?v=tAH5fy0rSo4|Youtube Linux Foundation]] -- Zephyr Project: RTOS Start-up and Initialization Flow * [[https://interrupt.memfault.com/blog/building-drivers-on-zephyr]] * [[https://community.circuitdojo.com/d/146-zephyr-driver-development-use-of-i2c-and-spi-apis]] == Real world examples == * [[https://github.com/zephyrproject-rtos/awesome-zephyr-rtos/tree/main]] -- Awezome Zephyr related list * [[https://github.com/xycloo/zephyr-examples/tree/master]] -- Rust examples * [[https://github.com/zmkfirmware/zmk/tree/main]] -- Zephyr Mechanical Keyboard * [[https://github.com/jakkra/ZSWatch/tree/main]] -- Open Source Smart Watch == Shawn Hymel / Digikey == * [[https://www.youtube.com/watch?v=mTJ_vKlMS_4|Introduction to Zephyr Part 1: Getting Started]] * [[https://www.youtube.com/watch?v=HSWazjB63cU|Introduction to Zephyr Part 2: CMake Tutorial]] * [[https://www.youtube.com/watch?v=dXx1Wc15NZE|Introduction to Zephyr Part 3: Kconfig Tutorial]] * [[https://www.youtube.com/watch?v=fOMJyjwowNk|Introduction to Zephyr Part 4: Devicetree Tutorial]] * [[https://www.youtube.com/watch?v=nL1kZ3kPyo0|Introduction to Zephyr Part 5: Devicetree Bindings]] * [[https://interrupt.memfault.com/blog/practical_zephyr_kconfig|Recommended KConfig page]] == Dokumentation == * [[https://docs.zephyrproject.org/apidoc/3.7.0/group__random__api.html|Zephyr API]] * [[https://docs.zephyrproject.org/3.7.0/services/crypto/random/index.html|Zephyr services]] * [[https://docs.zephyrproject.org/3.7.0/build/kconfig/index.html|Zephyr KConfig]] * [[https://cmake.org/cmake/help/v3.20/manual/cmake-commands.7.html|Cmake]] ===== Vanliga kommandon ===== Bygg Zephyr-projekt med overlay west build -p always -b esp32c6_devkitc -- -DDTC_OVERLAY_FILE=boards/esp32s3_devkitc.overlay Öppna menuconfig west build -p always -b esp32c6_devkitc -t menuconfig Bygg med extra conf file west build -p always -b esp32c6_devkitc -- -DEXTRA_CONF_FILE=boards/esp32s3_devkitc.conf Ladda kod python -m esptool --port COM19 --chip auto --baud 921600 --before default_reset --after hard_reset write_flash -u --flash_size detect 0x0 .\build\zephyr\zephyr.bin ===== Platser ===== | ''zephyr/dts////'' | .dtsi filer för olika chip | | ''zephyr/dts/bindings//.yaml'' | .yaml binding-filer för olika chips drivrutiner | | ''zephyr/boards///'' | .dts, Kconfig och default configs för boards | | ''zephyr/soc///soc.h'' | Startup-kod, HAL-includes etc för specifikt chip | | ''zephyr/arch//core/'' | Assembler-startup etc för specifik arkitektur | ===== CMake ===== === CMakeList.txt in project === cmake_minimum_required(VERSION 3.20.0) # Optional for your own extra KConfig modules set(ZEPHYR_EXTRA_MODULES "${CMAKE_SOURCE_DIR}/../../modules/say_hello") # Mandatory thing find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) # Name your project project(random) # Adds your main entry point to the Zephyr-created "app" lib target_sources(app PRIVATE src/main.c) === CMakeLists.txt === CMakeLists file for your own modules # Check if SAY_HELLO is set in Kconfig if(CONFIG_SAY_HELLO) # Add your include directory zephyr_include_directories(.) # Add the source file you want to compile zephyr_library_sources(say_hello.c) endif() ===== KConfig ===== Öppna menuconfig west build -p always -b esp32c6_devkitc -t menuconfig Sparas till ''./build/zephyr/.config'' som kommer tas bort vid nästa bygge. Generates an include file in ''build/zephyr/include/generated/zephyr/autoconf.h'' För att göra persistent, kolla diff mellan ./build/zephyr/.config.old # diff build/zephyr/.config.old build/zephyr/.config 574a575,576 > # CONFIG_STACK_CANARIES is not set > CONFIG_STACK_POINTER_RANDOM=0 1136c1138 < # CONFIG_TEST_RANDOM_GENERATOR is not set --- > CONFIG_TEST_RANDOM_GENERATOR=y 1137a1140,1141 > CONFIG_TIMER_RANDOM_GENERATOR=y > CONFIG_TEST_CSPRNG_GENERATOR=y Lägg sedan detta i antingen appens prj.conf eller ännu bättre i en board-specifik config # File: boards/esp32s3_devkitc.conf # CONFIG_STACK_CANARIES is not set CONFIG_STACK_POINTER_RANDOM=0 CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_TIMER_RANDOM_GENERATOR=y CONFIG_TEST_CSPRNG_GENERATOR=y # CONFIG_SAY_HELLO=y Och lägg med denna till bygget med ''-DEXTRA_CONF_FILE=boards/esp32s3_devkitc.conf'' west build -p always -b esp32c6_devkitc -- -DEXTRA_CONF_FILE=boards/esp32s3_devkitc.conf ==== Egna moduler ==== För att lägga till egna moduler som går att aktivera i menuconfig, lägg in en fil som heter exempelvis KConfig i modulens mapp. # Create a new option in menuconfig config SAY_HELLO bool "Basic print test to console" default n # Set the library to be disabled by default depends on PRINTK # Make it dependent on PRINTK help Adds say_hello() function to print a basic message to the console. Lägg även till en mapp som heter exakt ''zephyr'' i modulens mapp. Lägg in en fil som heter exakt ''module.yaml'' med likande innehåll. kconfig: pekar ut KConfig-filen ovan. name: say_hello build: cmake: . kconfig: Kconfig ===== Devicetree ===== * [[https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4/devicetree-specification-v0.4.pdf|Devicetree 0.4 specification]] * [[https://docs.zephyrproject.org/3.7.0/build/dts/index.html|Zephyr DTS page]] * [[https://docs.zephyrproject.org/3.7.0/build/dts/bindings-syntax.html|Zephyr DTS bindings]] The final devicetree will end up under ''build/zephyr/zephyr.dts''. There is an include file generated from this in ''build/zephyr/include/generated/zephyr/devicetree_generated.h'' === Words === * DTS -- Device Tree Source * DTC -- Device Tree Compiler * .dtsi -- Device Tree Source Include file === Property types === | string | ''status = "disabled";'' | | int | ''current-speed = <115200>;'' | | boolean | ''hw-flow-control;'' | | array 32bit | ''offsets = <0x100 0x200 0x300>;'' | | uint8-array | ''local-mac-address = [de ad be ef 12 34];'' | | string-array | ''dma-names = "tx", "rx";'' | | phandle | ''interrupt-parent = <&gic>;'' | | phandles | ''pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pd6>;'' | | phandle-array | ''dmas = <&dma0 2>, <&dma0 3>;'' | | path | ''zephyr,bt-c2h-uart = &uart0;'' or ''foo = "/path/to/some/node";'' | === Structure === [[https://docs.zephyrproject.org/3.7.0/build/dts/intro-syntax-structure.html|Zephyr DTS Syntax Structure]] In the boards folder for esp32s3_devkitc there is a DTS file for the appcpu, ''/opt/toolchains/zephyr/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu.dts''. /* * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; #include #include / { model = "Espressif ESP32S3-DevkitC APPCPU"; compatible = "espressif,esp32s3"; chosen { zephyr,sram = &sram0; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; }; }; &trng0 { status = "okay"; }; &ipm0 { status = "okay"; }; This ''#include '' includes a devicetree source include-file which in turn includes ''#include "esp32s3_common.dtsi"''. Int the file ''/opt/toolchains/zephyr/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi'' there is a part defining the alias ''gpio0'' for the path ''/soc/gpio/gpio@60004000''. gpio0: gpio@60004000 { compatible = "espressif,esp32-gpio"; gpio-controller; #gpio-cells = <2>; reg = <0x60004000 0x800>; interrupts = ; interrupt-parent = <&intc>; /* Maximum available pins (per port) * Actual occupied pins are specified * on part number dtsi level, using * the `gpio-reserved-ranges` property. */ ngpios = <32>; /* 0..31 */ }; The ''compatible = "espressif,esp32-gpio";'' tells Zephyr to look for a bindings file containing the similar line (file name doesn't really matter, but is by convention the same). Binding file can be found in ''/opt/toolchains/zephyr/dts/bindings/gpio/espressif,esp32-gpio.yaml'' # Copyright (c) 2019, Yannis Damigos # SPDX-License-Identifier: Apache-2.0 description: ESP32 GPIO controller compatible: "espressif,esp32-gpio" include: [gpio-controller.yaml, base.yaml] properties: reg: required: true "#gpio-cells": const: 2 gpio-cells: - pin - flags Also at the location for the board files is the ''/opt/toolchains/zephyr/boards/espressif/esp32s3_devkitc/esp32s3_devkitc-pinctrl.dtsi'' device tree source include file. The start of the file looks like this: /* * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include &pinctrl { uart0_default: uart0_default { group1 { pinmux = ; output-high; }; group2 { pinmux = ; bias-pull-up; }; }; i2c0_default: i2c0_default { group1 { pinmux = , ; bias-pull-up; drive-open-drain; output-high; }; }; The line ''#include '' refers to the file ''/opt/toolchains/zephyr/include/zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h'' which has a lot of defines used in the device tree include file. #define UART0_TX_GPIO43 ESP32_PINMUX(43, ESP_NOSIG, ESP_U0TXD_OUT) All of the files in ''/opt/toolchains/zephyr'' directories are default files and the device tree thingies can be overridden in you project with a overlay-file. === Lables, names, property names === [[https://docs.kernel.org/devicetree/bindings/dts-coding-style.html|Kernel DTS Coding Style]] * Names kan inte ha understreck, men kan ha bindestreck. * Lables kan inte ha bindestreck men kan ha understreck. * Names kan ha brädhögar och snabel-a i namnet, ingen magi. * Property names kan inte ha understreck, men kan ha bindestreck * I C-kod kommer bindestreck i aliases att automatiskt översättas till understreck === /chosen och /aliases === Dessa är två speciella noder i device-trädet som DTC behandlar speciellt. Dessa går att fylla på för att ställa in vissa saker eller introducera alias. / { chosen { zephyr,console = &uart0; }; aliases { my-uart = &uart0; }; soc { uart0: serial@12340000 { ... }; }; }; ==== Overlay files ==== == Example == ''boards/esp32s3_devkitc.overlay'' / { aliases { my-led = &led0; }; leds { compatible = "gpio-leds"; led0: d5 { gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; }; }; }; ===== C-kod ===== == Exempel blink == #include #include #include // Settings static const int32_t sleep_time_ms = 1000; static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(my_led), gpios); int main(void) { int ret; int state = 0; // Make sure that the GPIO was initialized if (!gpio_is_ready_dt(&led)) { return 0; } // Set the GPIO as output ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT); if (ret < 0) { return 0; } // Do forever while (1) { // Change the state of the pin and print state = !state; printk("LED state: %d\r\n", state); // Set pin state ret = gpio_pin_set_dt(&led, state); if (ret < 0) { return 0; } // Sleep k_msleep(sleep_time_ms); } return 0; }