From 0c4f14e0116a76af8387c1a6446d44bdff81577d Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Thu, 23 Feb 2023 20:50:13 +0200 Subject: [PATCH 1/2] ports/zephyr: Update to Zephyr 3.2.0. This commit updates the Zephyr port with the changes listed in https://docs.zephyrproject.org/3.2.0/releases/release-notes-3.2.html, specifically: - Changed `#include ` to `#include `. - Changed `FLASH_AREA_LABEL_EXISTS(storage)` to `FIXED_PARTITION_EXISTS(storage)`. - Changed Bluetooth include paths from `bluetooth/` to `zephyr/bluetooth`. Only minimal testing was done using a Nordic nRF5340-DK board (`nrf5340dk_nrf5340_cpuapp`): compile, flash, run some simple Python code), but the changes are cosmetic, not functional. The commit was also tested to work with the recent Zephyr 3.3.0 release. --- ports/zephyr/README.md | 6 +++--- ports/zephyr/machine_i2c.c | 2 +- ports/zephyr/machine_pin.c | 2 +- ports/zephyr/machine_spi.c | 2 +- ports/zephyr/machine_uart.c | 2 +- ports/zephyr/main.c | 4 ++-- ports/zephyr/modbluetooth_zephyr.c | 4 ++-- ports/zephyr/modusocket.c | 2 +- ports/zephyr/modutime.c | 2 +- ports/zephyr/modzephyr.c | 2 +- ports/zephyr/modzsensor.c | 2 +- ports/zephyr/mpconfigport.h | 2 +- ports/zephyr/mpconfigport_minimal.h | 2 +- ports/zephyr/mphalport.h | 2 +- ports/zephyr/src/zephyr_getchar.c | 2 +- ports/zephyr/src/zephyr_start.c | 2 +- ports/zephyr/zephyr_storage.c | 2 +- tools/ci.sh | 6 +++--- 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/ports/zephyr/README.md b/ports/zephyr/README.md index f9bd45344b322..bdeef523db7af 100644 --- a/ports/zephyr/README.md +++ b/ports/zephyr/README.md @@ -4,7 +4,7 @@ MicroPython port to Zephyr RTOS This is a work-in-progress port of MicroPython to Zephyr RTOS (http://zephyrproject.org). -This port requires Zephyr version v3.1.0, and may also work on higher +This port requires Zephyr version v3.2.0, and may also work on higher versions. All boards supported by Zephyr (with standard level of features support, like UART console) should work with MicroPython (but not all were tested). @@ -39,13 +39,13 @@ setup is correct. If you already have Zephyr installed but are having issues building the MicroPython port then try installing the correct version of Zephyr via: - $ west init zephyrproject -m https://github.com/zephyrproject-rtos/zephyr --mr v3.1.0 + $ west init zephyrproject -m https://github.com/zephyrproject-rtos/zephyr --mr v3.2.0 Alternatively, you don't have to redo the Zephyr installation to just switch from master to a tagged release, you can instead do: $ cd zephyrproject/zephyr - $ git checkout v3.1.0 + $ git checkout v3.2.0 $ west update With Zephyr installed you may then need to configure your environment, diff --git a/ports/zephyr/machine_i2c.c b/ports/zephyr/machine_i2c.c index c261ffad0d251..a1ad46ceb8bb4 100644 --- a/ports/zephyr/machine_i2c.c +++ b/ports/zephyr/machine_i2c.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include "py/runtime.h" diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c index be0698651bbf6..fad8bc9a3390b 100644 --- a/ports/zephyr/machine_pin.c +++ b/ports/zephyr/machine_pin.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include "py/runtime.h" diff --git a/ports/zephyr/machine_spi.c b/ports/zephyr/machine_spi.c index 507d839c66442..c850181d8134b 100644 --- a/ports/zephyr/machine_spi.c +++ b/ports/zephyr/machine_spi.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include "py/runtime.h" diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c index b989c0f4817c4..e5af03c3382b2 100644 --- a/ports/zephyr/machine_uart.c +++ b/ports/zephyr/machine_uart.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include "py/runtime.h" diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index 869449e7df473..14d2076befb16 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -29,7 +29,7 @@ #include #include -#include +#include #ifdef CONFIG_NETWORKING #include #endif @@ -106,7 +106,7 @@ STATIC void vfs_init(void) { mp_obj_t args[] = { mp_obj_new_str(CONFIG_SDMMC_VOLUME_NAME, strlen(CONFIG_SDMMC_VOLUME_NAME)) }; bdev = MP_OBJ_TYPE_GET_SLOT(&zephyr_disk_access_type, make_new)(&zephyr_disk_access_type, ARRAY_SIZE(args), 0, args); mount_point_str = "/sd"; - #elif defined(CONFIG_FLASH_MAP) && FLASH_AREA_LABEL_EXISTS(storage) + #elif defined(CONFIG_FLASH_MAP) && FIXED_PARTITION_EXISTS(storage) mp_obj_t args[] = { MP_OBJ_NEW_SMALL_INT(FLASH_AREA_ID(storage)), MP_OBJ_NEW_SMALL_INT(4096) }; bdev = MP_OBJ_TYPE_GET_SLOT(&zephyr_flash_area_type, make_new)(&zephyr_flash_area_type, ARRAY_SIZE(args), 0, args); mount_point_str = "/flash"; diff --git a/ports/zephyr/modbluetooth_zephyr.c b/ports/zephyr/modbluetooth_zephyr.c index 4d4b19a1d98c5..d0ecd2f9f62e4 100644 --- a/ports/zephyr/modbluetooth_zephyr.c +++ b/ports/zephyr/modbluetooth_zephyr.c @@ -31,8 +31,8 @@ #if MICROPY_PY_BLUETOOTH -#include -#include +#include +#include #include "extmod/modbluetooth.h" #define DEBUG_printf(...) // printk("BLE: " __VA_ARGS__) diff --git a/ports/zephyr/modusocket.c b/ports/zephyr/modusocket.c index c79f73a9d2759..d06063da8a17d 100644 --- a/ports/zephyr/modusocket.c +++ b/ports/zephyr/modusocket.c @@ -31,7 +31,7 @@ #include "py/stream.h" #include -#include +#include // Zephyr's generated version header #include #include diff --git a/ports/zephyr/modutime.c b/ports/zephyr/modutime.c index c1c2be1c07c75..c56a8002126d3 100644 --- a/ports/zephyr/modutime.c +++ b/ports/zephyr/modutime.c @@ -28,7 +28,7 @@ #include "py/mpconfig.h" #if MICROPY_PY_UTIME -#include +#include #include "py/runtime.h" #include "py/smallint.h" diff --git a/ports/zephyr/modzephyr.c b/ports/zephyr/modzephyr.c index f87e2e33f3c78..c25351bffaf37 100644 --- a/ports/zephyr/modzephyr.c +++ b/ports/zephyr/modzephyr.c @@ -29,7 +29,7 @@ #if MICROPY_PY_ZEPHYR #include -#include +#include #include #include #include diff --git a/ports/zephyr/modzsensor.c b/ports/zephyr/modzsensor.c index e35a1716f473f..f5b0742c0e828 100644 --- a/ports/zephyr/modzsensor.c +++ b/ports/zephyr/modzsensor.c @@ -28,7 +28,7 @@ #include "py/runtime.h" -#include +#include #include #if MICROPY_PY_ZSENSOR diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h index 71836768a44c5..12302a1834d96 100644 --- a/ports/zephyr/mpconfigport.h +++ b/ports/zephyr/mpconfigport.h @@ -28,7 +28,7 @@ // Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles #include "autoconf.h" // Included here to get basic Zephyr environment (macros, etc.) -#include +#include #include // Usually passed from Makefile diff --git a/ports/zephyr/mpconfigport_minimal.h b/ports/zephyr/mpconfigport_minimal.h index e819d5cf41ca0..bb284419fbbef 100644 --- a/ports/zephyr/mpconfigport_minimal.h +++ b/ports/zephyr/mpconfigport_minimal.h @@ -28,7 +28,7 @@ // Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles #include "autoconf.h" // Included here to get basic Zephyr environment (macros, etc.) -#include +#include // Usually passed from Makefile #ifndef MICROPY_HEAP_SIZE diff --git a/ports/zephyr/mphalport.h b/ports/zephyr/mphalport.h index 615859391167a..8206de54bccc9 100644 --- a/ports/zephyr/mphalport.h +++ b/ports/zephyr/mphalport.h @@ -1,4 +1,4 @@ -#include +#include #include "shared/runtime/interrupt_char.h" void mp_hal_init(void); diff --git a/ports/zephyr/src/zephyr_getchar.c b/ports/zephyr/src/zephyr_getchar.c index 5bbf1a9f68e7d..cade05d83c4a5 100644 --- a/ports/zephyr/src/zephyr_getchar.c +++ b/ports/zephyr/src/zephyr_getchar.c @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include #include diff --git a/ports/zephyr/src/zephyr_start.c b/ports/zephyr/src/zephyr_start.c index b24e501c33363..bdc4fd4d06354 100644 --- a/ports/zephyr/src/zephyr_start.c +++ b/ports/zephyr/src/zephyr_start.c @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include #include #include "zephyr_getchar.h" diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index 498fea6fb1c8d..c5059e8517075 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -244,7 +244,7 @@ STATIC const mp_rom_map_elem_t zephyr_flash_area_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&zephyr_flash_area_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&zephyr_flash_area_writeblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&zephyr_flash_area_ioctl_obj) }, - #if FLASH_AREA_LABEL_EXISTS(storage) + #if FIXED_PARTITION_EXISTS(storage) { MP_ROM_QSTR(MP_QSTR_STORAGE), MP_ROM_INT(FLASH_AREA_ID(storage)) }, #endif }; diff --git a/tools/ci.sh b/tools/ci.sh index 9146291505eb1..30c96d1b7e261 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -675,9 +675,9 @@ function ci_windows_build { ######################################################################################## # ports/zephyr -ZEPHYR_DOCKER_VERSION=v0.21.0 -ZEPHYR_SDK_VERSION=0.13.2 -ZEPHYR_VERSION=v3.1.0 +ZEPHYR_DOCKER_VERSION=v0.24.3 +ZEPHYR_SDK_VERSION=0.15.0 +ZEPHYR_VERSION=v3.2.0 function ci_zephyr_setup { docker pull zephyrprojectrtos/ci:${ZEPHYR_DOCKER_VERSION} From de5c3caa48204380f3e7f4022f26be94e965a10a Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Mon, 27 Feb 2023 20:22:23 +0200 Subject: [PATCH 2/2] INCOMPLETE: use "friendly" names for GPIO ports Starting with Zephyr 3.2.0, the `label` property of DT nodes was made obsolete, which means that is no longer possible to write: ``` pin = Pin(("GPIO_1", 21), Pin.IN) ``` Instead, a much less friendly format must be used: ``` pin = Pin(("gpio@842500", 21), Pin.IN) ``` This commit adds a new script (`gen_dt_node_names.py`) which is heavily based on [this script](https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/dts/gen_dts_cmake.py) and attempts to generate and map friendly names for DT nodes. For example, a node defined like this: ``` gpio0: gpio@842500 { ... } ``` will generate a mapping like this: ``` struct dt_node_name_map { const char *const gen_name; const char *const actual_name; }; static const struct dt_node_name_map dt_node_map[] = { {"GPIO_0", "gpio@842500"} ... } ``` The code then checks this mapping if the node name supplied by the user does not exist and uses the actual DT name instead. --- ports/zephyr/CMakeLists.txt | 6 +++ ports/zephyr/gen_dt_node_names.py | 68 +++++++++++++++++++++++++++++++ ports/zephyr/machine_pin.c | 9 ++++ 3 files changed, 83 insertions(+) create mode 100644 ports/zephyr/gen_dt_node_names.py diff --git a/ports/zephyr/CMakeLists.txt b/ports/zephyr/CMakeLists.txt index bd5068faf3bef..7cbef57e7fecd 100644 --- a/ports/zephyr/CMakeLists.txt +++ b/ports/zephyr/CMakeLists.txt @@ -28,6 +28,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(micropython) set(MICROPY_PORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(MICROPY_BUILD_DIR ${MICROPY_PORT_DIR}/build) set(MICROPY_DIR ${MICROPY_PORT_DIR}/../..) set(MICROPY_TARGET micropython) @@ -74,7 +75,12 @@ set(MICROPY_SOURCE_LIB ) list(TRANSFORM MICROPY_SOURCE_LIB PREPEND ${MICROPY_DIR}/lib/) +add_custom_command(OUTPUT ${MICROPY_BUILD_DIR}/gen_dt_node_names.h + DEPENDS ${MICROPY_BUILD_DIR}/zephyr/edt.pickle ${MICROPY_PORT_DIR}/gen_dt_node_names.py + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PORT_DIR}/gen_dt_node_names.py -i ${MICROPY_BUILD_DIR}/zephyr/edt.pickle -o ${MICROPY_BUILD_DIR}/gen_dt_node_names.h) + set(MICROPY_SOURCE_QSTR + ${MICROPY_BUILD_DIR}/gen_dt_node_names.h ${MICROPY_SOURCE_PY} ${MICROPY_SOURCE_EXTMOD} ${MICROPY_SOURCE_SHARED} diff --git a/ports/zephyr/gen_dt_node_names.py b/ports/zephyr/gen_dt_node_names.py new file mode 100644 index 0000000000000..e1d3a1b4630de --- /dev/null +++ b/ports/zephyr/gen_dt_node_names.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys +import pickle +import re + +# This is needed by the "pickle.load" call below +zephyr_base = os.environ["ZEPHYR_BASE"] +sys.path.insert(0, os.path.join(zephyr_base, "scripts", "dts", "python-devicetree", "src")) + +# The prefixes to look for in the device tree +prefixes = ("gpio", "spi", "i2c", "uart") + +# Prefix for the generated header +header_prefix = """#ifndef MICROPY_INCLUDED_ZEPHYR_GEN_DT_NODE_NAMES_H +#define MICROPY_INCLUDED_ZEPHYR_GEN_DT_NODE_NAMES_H + +struct dt_node_name_map { + const char *const gen_name; + const char *const actual_name; +}; + +static const struct dt_node_name_map dt_node_map[] = { +""" +# Suffix for the generated header +header_sufix = """}; + +#endif +""" + +def main(): + parser = argparse.ArgumentParser(description="Generate friendly names for Zephyr DT nodess") + parser.add_argument("-i", "--input", required=True, help="path to edt.pickle") + parser.add_argument("-o", "--output", required=True, help="path to the output file") + args = parser.parse_args() + + # Load the representation of the device tree generated by Zephyr + with open(args.input, 'rb') as f: + edt = pickle.load(f) + + # Create regular expressions for all prefix that we need to check + all_re = re.compile(fr'^({"|".join(prefixes)})(\d+)$') + + # Look in the device tree for all nodes with labels + name_map = {} + for n in edt.nodes: + if n.status == "okay": # consider only nodes that are enabled + # Check prefixes for all labels + for l in n.labels: + found = all_re.match(l) + if found != None: + # Transform name (from "gpio0" to "GPIO_0" and so on) + new_name = found.group(1).upper() + "_" + found.group(2) + name_map[new_name] = n.name + break + + # Write data to output file + with open(args.output, "wt") as f: + f.write(header_prefix) + for n in name_map: + f.write(f' {{"{n}", "{name_map[n]}"}},\n') + f.write(" {NULL, NULL}\n") + f.write(header_sufix) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ports/zephyr/machine_pin.c b/ports/zephyr/machine_pin.c index fad8bc9a3390b..dc8651cf24f69 100644 --- a/ports/zephyr/machine_pin.c +++ b/ports/zephyr/machine_pin.c @@ -37,6 +37,7 @@ #include "py/mphal.h" #include "shared/runtime/mpirq.h" #include "modmachine.h" +#include "gen_dt_node_names.h" #if MICROPY_PY_MACHINE @@ -133,6 +134,14 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const char *drv_name = mp_obj_str_get_str(items[0]); int wanted_pin = mp_obj_get_int(items[1]); const struct device *wanted_port = device_get_binding(drv_name); + if (!wanted_port) { + for (const struct dt_node_name_map *m = &dt_node_map[0]; m->gen_name != NULL; m ++) { + if (!strcmp(m->gen_name, drv_name)) { + wanted_port = device_get_binding(m->actual_name); + break; + } + } + } if (!wanted_port) { mp_raise_ValueError(MP_ERROR_TEXT("invalid port")); }